首页 > 其他分享 >链表详解

链表详解

时间:2023-08-31 19:55:41浏览次数:64  
标签:current head list next 链表 详解 节点

C++中的链表是一种数据结构,用于存储一系列元素,每个元素都包含一个值以及一个指向下一个元素的指针。链表可以分为单向链表和双向链表,其中单向链表每个节点只有一个指向下一个节点的指针,而双向链表每个节点有一个指向下一个节点和一个指向前一个节点的指针。

以下是关于C++链表的详细解释:

  1. 链表节点的定义:

    链表的节点是一个自定义的结构体或类,它包含两个主要部分:数据(元素的值)和指针(指向下一个节点或前一个节点的指针)。

    struct Node {
        int data;       // 存储节点的数据
        Node* next;     // 指向下一个节点的指针
    };
    

    对于双向链表,Node结构会有一个额外的指针,指向前一个节点:

    struct DoubleNode {
        int data;           // 存储节点的数据
        DoubleNode* next;   // 指向下一个节点的指针
        DoubleNode* prev;   // 指向前一个节点的指针(仅在双向链表中)
    };
    
  2. 链表的操作:

    链表支持插入、删除、查找等操作。以下是一些常见的链表操作:

    • 插入节点: 插入新节点通常涉及调整指针来建立新节点与前一个节点和后一个节点的关系。

    • 删除节点: 删除节点也需要调整指针,使前一个节点指向后一个节点,从而绕过要删除的节点。

    • 查找节点: 遍历链表以找到特定值或位置的节点。

  3. 链表的遍历:

    遍历链表意味着按顺序访问链表中的每个节点。这可以通过使用循环(通常是while循环)来实现。

    Node* current = head; // 从头节点开始遍历
    while (current != nullptr) {
        // 处理当前节点
        // ...
        current = current->next; // 移动到下一个节点
    }
    
  4. 链表的优势和劣势:

    • 优势: 链表在插入和删除节点时的效率较高,因为只需要调整指针。与数组不同,它不需要预留固定大小的内存。

    • 劣势: 链表的随机访问效率较低,因为必须从头开始遍历。此外,链表需要额外的内存来存储指针。

总之,链表是一种常见的数据结构,用于在C++中存储和管理一系列元素。它们可以用于各种情况,特别是在需要频繁插入和删除元素的场景中。

当涉及到C++链表的例子时,我们可以看一下如何手动实现一个简单的单向链表,以及如何使用C++标准库中的std::list来创建和操作链表。

手动实现单向链表的例子:

#include <iostream>

// 定义链表节点
struct Node {
    int data;
    Node* next;
    Node(int value) : data(value), next(nullptr) {}
};

// 定义链表类
class LinkedList {
private:
    Node* head;

public:
    LinkedList() : head(nullptr) {}

    // 插入节点到链表开头
    void insert(int value) {
        Node* newNode = new Node(value);
        newNode->next = head;
        head = newNode;
    }

    // 遍历并打印链表
    void display() {
        Node* current = head;
        while (current != nullptr) {
            std::cout << current->data << " ";
            current = current->next;
        }
        std::cout << std::endl;
    }

    // 清理链表内存
    ~LinkedList() {
        Node* current = head;
        while (current != nullptr) {
            Node* temp = current;
            current = current->next;
            delete temp;
        }
    }
};

int main() {
    LinkedList list;
    list.insert(3);
    list.insert(7);
    list.insert(12);
    list.display();
    return 0;
}

这个例子展示了如何手动实现一个简单的单向链表,包括插入节点和遍历链表。

使用std::list标准库的例子:

#include <iostream>
#include <list>

int main() {
    std::list<int> myList;
    myList.push_back(5);
    myList.push_front(3);
    myList.push_back(8);

    // 使用迭代器遍历并打印链表
    for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

这个例子展示了如何使用C++标准库中的std::list来创建和操作链表,包括插入节点并使用迭代器遍历链表。




如何手动实现一个简单的双向链表,并演示如何在双向链表中插入、删除和遍历节点。

手动实现双向链表的例子:

#include <iostream>

// 定义链表节点
struct DoubleNode {
    int data;
    DoubleNode* next;
    DoubleNode* prev;
    DoubleNode(int value) : data(value), next(nullptr), prev(nullptr) {}
};

// 定义双向链表类
class DoublyLinkedList {
private:
    DoubleNode* head;
    DoubleNode* tail;

public:
    DoublyLinkedList() : head(nullptr), tail(nullptr) {}

    // 插入节点到链表末尾
    void insert(int value) {
        DoubleNode* newNode = new DoubleNode(value);
        if (!head) {
            head = newNode;
            tail = newNode;
        } else {
            newNode->prev = tail;
            tail->next = newNode;
            tail = newNode;
        }
    }

    // 删除节点
    void remove(int value) {
        DoubleNode* current = head;
        while (current) {
            if (current->data == value) {
                if (current->prev) {
                    current->prev->next = current->next;
                } else {
                    head = current->next;
                }
                if (current->next) {
                    current->next->prev = current->prev;
                } else {
                    tail = current->prev;
                }
                delete current;
                break;
            }
            current = current->next;
        }
    }

    // 遍历并打印链表
    void display() {
        DoubleNode* current = head;
        while (current) {
            std::cout << current->data << " ";
            current = current->next;
        }
        std::cout << std::endl;
    }

    // 清理链表内存
    ~DoublyLinkedList() {
        DoubleNode* current = head;
        while (current) {
            DoubleNode* temp = current;
            current = current->next;
            delete temp;
        }
    }
};

int main() {
    DoublyLinkedList list;
    list.insert(3);
    list.insert(7);
    list.insert(12);
    list.display();

    list.remove(7);
    list.display();

    return 0;
}

这个例子展示了如何手动实现一个简单的双向链表,包括插入、删除和遍历节点。

在这个例子中,DoublyLinkedList类定义了插入、删除和遍历操作,演示了双向链表的基本用法。当然,实际应用中可能还会有更多的操作和处理。

标签:current,head,list,next,链表,详解,节点
From: https://www.cnblogs.com/itlaoboy/p/17670305.html

相关文章

  • XGboost详解
    一概述XGBoost提供梯度提升树(也称为GBDT,GBM),可以快速准确地解决许多数据科学问题,相同的代码可以在主要分布式环境运行(ApacheHadoop,ApacheSpark,ApacheFlink)。系统优化:并行计算:支持并行计算。树剪枝:用贪心算法来选择最佳分裂点,然后开始剪枝。硬件优化:有效利用硬件资源。......
  • [转]C#下使用XmlDocument操作XML详解
    C#下使用XmlDocument操作XML详解发布时间:2023/06/08  目录一、XMLDOM概述二、XML成员1、XMl节点:XmlNode1、属性:2、方法:2、XML文档:XMLDocument1、属性:2、方法:3、事件:3、XML元素:XmlElement1、属性:2、方法:三、创建......
  • 详解 canal 同步 MySQL 增量数据到 ES
    canal是阿里知名的开源项目,主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费。这篇文章,我们手把手向同学们展示使用canal将MySQL增量数据同步到ES。1集群模式图中server对应一个canal运行实例,对应一个JVM。server中包含1..n个instance,我......
  • 4.python的列表详解
    当涉及到Python的列表操作时,有许多可用的方法和操作,以下是一些常见的列表操作总结:创建列表:my_list=[1,2,3,4,5]empty_list=[]mixed_list=[1,"hello",3.14,True]访问和修改元素:value=my_list[2]#获取索引为2的元素值my_list[3]=10#......
  • Java中的ThreadLocal详解
     一、ThreadLocal简介多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。ThreadLocal是除了加锁这种同步方式之外的一种保证一种规避多线......
  • JPA EntityManager详解
    JPAEntityManager详解(一) 通过本章的学习,读者将深入掌握JPA中有关持久化上下文、事务处理的相关知识,从而能够更加深入地应用JPA。 11.1获得EntityManager对象 那么如何获得EntityManager对象呢?这又是JPA中另外一个很重要的问题......
  • html5之拖放详解
    拖放是一种常见的特性,即抓取对象以后拖到另一个位置。在HTML5中,拖放是标准的一部分,任何元素都能够拖放。InternetExplorer9、Firefox、Opera12、Chrome以及Safari5支持拖放。1.drggable属性如果网页元素的draggable元素为true,这个元素就是可以拖动的。<div draggable......
  • 【剑指Offer】15、反转链表
    【剑指Offer】15、反转链表题目描述:输入一个链表,反转链表后,输出新链表的表头。解题思路:本题比较简单,有两种方法可以实现:(1)三指针。使用三个指针,分别指向当前遍历到的结点、它的前一个结点以及后一个结点。将指针反转后,三个结点依次前移即可。(2)递归方法。同样可以采用递归来实现......
  • 【性能测试】ulimit命令说明与用法-详解
    目录1、ulimit命令与显示说明2.常用操作-ulimit是临时修改-程序要使用配置得重启3、永久修改的话修改配置文件正文1、ulimit命令与显示说明ulimit命令是Linux系统的内建功能,它具有一套参数集,用于控制shell进程及其所创进程的资源使用限制。它主要用于设置用户和系......
  • 剑指Offer 35. 复杂链表的复制
    题目链接:剑指Offer35.复杂链表的复制题目描述:请实现copyRandomList函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个next指针指向下一个节点,还有一个random指针指向链表中的任意节点或者null。解法思路:遍历整个链表,在每个节点的后面,插入一个当前节点的复制,......