数据结构——链表(C++)

本文介绍了链表作为一种动态数据结构的基本概念,重点讲解了如何在C++中实现链表的创建、遍历、插入、删除、查找和更新节点的功能,以及链表的销毁操作。
什么是链表:

链表是一种基本的线性数据结构,它由一系列节点组成,每个节点包含数据和对下一个节点的引用。链表的每个节点都有一个存储数据的字段和一个指向下一个节点的指针。链表的起始节点称为头节点,指向第一个数据节点的指针称为头指针。链表的最后一个节点没有指向其他节点的指针,称为尾节点。

链表的主要优点在于它的动态特性和灵活性。与数组不同,链表不需要预先分配固定大小的存储空间,它可以在运行时根据需要动态地添加或删除节点。这使得链表在处理动态变化的场景中非常有用。此外,链表可以通过指针方便地进行节点的插入和删除操作,这在某些情况下可以提高效率。

链表的操作:

在C++中,链表的基本操作包括但不限于以下几种:

1. 创建链表:初始化一个链表,包括分配内存给头节点,并为头节点设置适当的指针。

#include <iostream>

struct ListNode {
    int val; // 节点值
    ListNode *next; // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {} // 构造函数
};

int main() {
    // 创建头节点并分配内存
    ListNode *head = new ListNode(0);
    }
}


2. 遍历链表:通过指针依次访问链表中的每个节点,执行特定操作。

//遍历并打印链表
    ListNode *cur = head->next;// 初始化当前指针为头节点的下一个节点
    while (cur != NULL) {// 循环遍历链表
        std::cout << cur->val << " ";// 访问当前节点的值并打印
        cur = cur->next;//// 移动指针到下一个节点


3. 插入节点:在链表的指定位置插入一个新的节点。

void insertNode(ListNode *head, int val) {
    ListNode *cur = head; // 创建一个指针 cur,指向链表的头节点
    while (cur->next != NULL && cur->next->val < val) {
        cur = cur->next; // 当 cur 指向的下一个节点不为空且其值小于要插入的值val时,继续向后移动cur指针
    }
    ListNode *node = new ListNode(val); // 创建一个新的节点 node,值为 val
    node->next = cur->next; // 将 node 的 next 指向 cur 指向的下一个节点
    cur->next = node; // 将 cur 指向的下一个节点指向新插入的节点 node
}


4. 删除节点:移除链表中的一个节点,并调整指针以保持链表的结构完整性。

void deleteNode(ListNode *head, int val) {
    ListNode *cur = head;
    while (cur->next != NULL && cur->next->val != val) {
        cur = cur->next;
    }
    if (cur->next != NULL) {
        ListNode *temp = cur->next;
        cur->next = cur->next->next;
        delete temp;
    }
}


5. 查找节点:在链表中寻找具有特定值的节点。

ListNode* findNode(ListNode *head, int val) {
    ListNode *cur = head;
    while (cur != NULL && cur->val != val) {//使用一个循环遍历链表,直到找到值为val的节点或者到达链表末尾
        cur = cur->next;//将cur指向下一个节点。
    }
    return cur;//返回指向值为val的节点的指针(即`cur`)
}


6. 更新节点:改变链表中某个节点的数据值。

void updateNode(ListNode *head, int oldVal, int newVal) {
    ListNode *cur = head;
    while (cur != NULL && cur->val != oldVal) {
        cur = cur->next;
    }
    if (cur != NULL) {
        cur->val = newVal;
    }
}


7. 销毁链表:释放链表占用的所有内存资源。
 

void destroyList(ListNode *head) {
    ListNode *cur = head;
    while (cur != NULL) {
        ListNode *temp = cur;
        cur = cur->next;
        delete temp;
    }
}

C++ 链表是一种基础且重要的数据结构,在计算机科学领域应用广泛。它通过节点间的指针链接来存储数据,与数组的连续存储方式不同。 ### 链表的实现 - **单向链表**:在 C++ 中,单向链表节点通常包含数据域和指向下一个节点的指针。虽然未给出单向链表节点的具体代码,但基本结构可类比双向链表节点,即一个数据域和一个指向下一节点的指针。 - **双向链表**:双向链表在单向链表基础上增加了一个指向前一个节点的指针。以下是双向链表节点结构体及创建新节点函数的代码示例: ```cpp // 双向链表节点结构体 typedef struct DNode { int data; struct DNode *prev; struct DNode *next; } DNode; // 创建新节点的函数 DNode* createDNode(int data) { DNode *newNode = (DNode*)malloc(sizeof(DNode)); newNode->data = data; newNode->prev = NULL; newNode->next = NULL; return newNode; } ``` 此外,还有使用模板实现的双链表节点结构: ```cpp // 双链表节点结构 template <typename T> struct DoublyNode { T data; // 数据域 DoublyNode* prev; // 指向前驱节点 DoublyNode* next; // 指向后继节点 DoublyNode(const T& val) : data(val), prev(nullptr), next(nullptr) {} }; ``` ### 链表的应用场景 链表适用于需要频繁进行插入和删除操作的场景,在内存管理、缓冲区管理、动态内存分配等方面有广泛应用。例如,操作系统中的任务调度和内存管理,就经常使用链表来管理任务和内存块。链表也是队列、栈和哈希表等数据结构的实现基础 [^1][^5]。 ### 链表的操作技巧 在 C++ 中对链表进行操作时,如排序操作,可使用归并排序,示例代码如下: ```cpp list_head->next = MergeSort(list_head->next); for_each(pow, list_head) cout<<pow->data<<"\t"; cout<<endl; ``` 这段代码先对链表进行归并排序,然后遍历链表输出每个节点的数据 [^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值