小工具知识网

当前位置: 首页 > 行业知识 > C语言/C++实现链表的详细教程

行业知识

C语言/C++实现链表的详细教程

2026-10-21 19:31:09 来源:互联网转载

C语言/C++实现链表的详细教程

1. 什么是链表

��表是一种常用的数据结构,它由一系列节点组成,每个节点包含两部分内容:数据和指向下一个节点的指针,最后一个节点指向空。链表的节点可以动态添加和删除,因此可以方便地进行插入、删除等操作。链表有多种类型,包括单向链表、双向链表和循环链表等。

()
1.1 单向链表(Singly Linked List)

单向链表是最简单的链表类型,它的每个节点只包含一个指向下一个节点的指针。单向链表的优点是插入和删除节点的速度较快,但查找节点的速度较慢。单向链表的数据结构如下所示:

cstruct ListNode {    int val;  // 节点的值    struct ListNode *next;  // 指向下一个节点的指针};
1.2 双向链表(Doubly Linked List)

双向链表是在单向链表的基础上增加了一个指向前一个节点的指针。这样一来,双向链表可以从前往后遍历,也可以从后往前遍历,但相应地,插入和删除节点的操作会稍微复杂一些。双向链表的数据结构如下所示:

()
cstruct ListNode {    int val;  // 节点的值    struct ListNode *prev;  // 指向前一个节点的指针    struct ListNode *next;  // 指向下一个节点的指针};
1.3 循环链表(Circular Linked List)

循环链表是一种特殊的链表类型,它的最后一个节点指向第一个节点(或者说,第一个节点指向最后一个节点)。这样一来,循环链表可以无限循环下去,因此常用于循环队列等数据结构中。循环链表的数据结构和单向链表或双向链表类似,只是最后一个节点的指针指向第一个节点。

本教程主要演示的是单向链表的使用。

2. 节点的定义

首先,我们需要定义链表的节点结构。每个节点包含一个数据元素和一个指向下一个节点的指针。在C语言中,我们可以使用结构体来定义节点。

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

3. 创建和初始化链表

下面是一个函数,用于创建并初始化一个空链表。

Node* createLinkedList() {    return NULL;  // 返回空链表}

4. 插入节点

接下来,我们需要实现在链表中插入新节点的功能。我们可以根据需要在链表的开头、末尾或中间插入新节点。

// 插入节点到链表开头Node *insertAtBeginning(Node *head, int data) {    // 创建新节点Node *newNode = (Node*)malloc(sizeof(Node));      // 设置节点数据newNode->data = data;  // 将新节点指向原来的头节点                            newNode->next = head; // 返回新的链表头节点                             return newNode;                                }// 插入节点到链表末尾Node *insertAtEnd(Node *head, int data) {    // 创建新节点Node *newNode = (Node*)malloc(sizeof(Node));     newNode->data = data;    // 将新节点的下一个节点指针设置为NULL    newNode->next = NULL;                          // 如果链表为空,将新节点作为链表的唯一节点    if (head == NULL) {        return newNode;      }    Node* current = head;    // 遍历链表直到达到最后一个节点    while (current->next != NULL) {        current = current->next;    }// 将新节点插入到已有链表的末尾    current->next = newNode;      // 返回原来的头节点    return head;              }// 在指定位置插入节点Node* insertAtPosition(Node* head, int data, int position) {    // 创建新节点Node* newNode = (Node*)malloc(sizeof(Node));      newNode->data = data; // 如果插入位置为0,则将新节点作为新的头节点    if (position == 0) {        newNode->next = head;        return newNode;     }    Node* current = head;    // 找到插入位置的前一个节点    for (int i = 0; i next;    }// 将新节点的next指针指向当前位置的节点    newNode->next = current->next;      // 将当前位置的节点指向新节点current->next = newNode;            // 返回原来的头节点return head;                    }

5. 删除节点

我们也可以从链表中删除节点。下面是一些用于删除节点的函数示例。

// 从链表开头删除节点Node* deleteAtBeginning(Node* head) {    if (head == NULL) {        printf("链表为空");        return NULL;    }    Node* temp = head;    // 更新头节点    head = head->next;      // 释放删除节点的内存    free(temp);  // 返回新的头节点           return head;        }// 从链表末尾删除节点Node* deleteAtEnd(Node* head) {    if (head == NULL) {        printf("链表为空!!!\n");        return NULL;    }// 如果只有一个节点,直接删除    if (head->next == NULL) {        free(head);           return NULL;    }    Node *current = head, *prev;    // 找到倒数第二个节点    while (current->next != NULL) {        prev = current;        current = current->next;    }//将倒数第二个节点的next指针设置为NULL,删除最后一个节点    prev->next = NULL;      // 释放删除节点的内存free(current);          // 返回原来的头节点return head;        }// 根据数据值删除节点Node* deleteByValue(Node* head, int data) {    if (head == NULL) {        printf("链表为空!!!\n");        return NULL;    }    Node *current = head, *prev;    // 遍历链表找到要删除的节点    while (current != NULL && current->data != data) {        prev = current;        current = current->next;    }    if (current == NULL) {        printf("数据不存在!!!\n");        return head;    }    if (current == head) {        //如果删除节点是头节点,则更新头节点head = head->next;      } else {    //将前一个节点的next指针跳过删除节点        prev->next = current->next;     }    free(current);// 释放删除节点的内存    return head;}

6. 打印链表

为了验证链表的操作,我们可以编写一个函数来打印链表的所有节点。

//打印链表数据 void printList(Node* head) {    Node* current = head;    printf("链表所存数据: ");//表头为空,结束循环     while (current != NULL) {        printf("%d ", current->data);        current = current->next;    }    printf("\n");}

7. 测试代码

我们可以编写一段测试代码来验证我们的链表代码:

//主函数 int main() {//创建链表     Node* head = createLinkedList();    printf("链表已经创建完成,可以正常使用!!!\n");while(true){printf("1、添加新的数据到链表头。\n"); printf("2、添加新的数据到链表尾。\n");printf("3、添加新的数据到固定位置。\n");printf("4、删除链表头的数据。\n");printf("5、删除链表尾的数据。\n");printf("6、删除指定数据。\n");printf("7、退出程序。\n");printf("请输入你的选择:");int ch;bool flag=false;scanf("%d",&ch);system("cls");switch(ch){case 1:int insertN;printf("请输入需要插入的数据:");scanf("%d",&insertN); head = insertAtBeginning(head, insertN);break;case 2:int insertEndN;printf("请输入需要插入的数据:");scanf("%d",&insertEndN);head = insertAtEnd(head, insertEndN);break;case 3:int insertPosN,pos;printf("请输入需要插入的数据和位置:");scanf("%d %d",&insertPosN,&pos);head = insertAtPosition(head, insertPosN, pos-1);break;case 4:head = deleteAtBeginning(head);break;case 5:head = deleteAtEnd(head);break;case 6:int delN;printf("请输入需要删除的数据:");scanf("%d",&delN); head = deleteByValue(head, delN);break;case 7:printf("程序结束,欢迎使用。\n");exit(0);default:printf("您的输入有误,请检查后重新输入!\n");flag=true;break;}if(!flag){printf("****-----------------------------****\n");printList(head);printf("****-----------------------------****\n\n");}getchar();}    return 0;}

8. 总结

恭喜你!你已经完成了C语言实现链表的教程。链表是一种非常有用的数据结构,可以在运行时动态管理数据。通过学习链表的实现,您可以对如何操作和管理数据有更深入的了解。希望本教程对你有所帮助,谢谢!

9. 完整代码

#include #include typedef struct Node {    int data;           // 数据元素    struct Node *next;  // 指向下一个节点的指针} Node;//创建并初始化链表Node *createLinkedList() {    return NULL;  // 返回空链表}// 插入节点到链表开头Node *insertAtBeginning(Node *head, int data) {    // 创建新节点Node *newNode = (Node*)malloc(sizeof(Node));      // 设置节点数据newNode->data = data;  // 将新节点指向原来的头节点                            newNode->next = head; // 返回新的链表头节点                             return newNode;                                }// 插入节点到链表末尾Node *insertAtEnd(Node *head, int data) {    // 创建新节点Node *newNode = (Node*)malloc(sizeof(Node));     newNode->data = data;    // 将新节点的下一个节点指针设置为NULL    newNode->next = NULL;                          // 如果链表为空,将新节点作为链表的唯一节点    if (head == NULL) {        return newNode;      }    Node* current = head;    // 遍历链表直到达到最后一个节点    while (current->next != NULL) {        current = current->next;    }// 将新节点插入到已有链表的末尾    current->next = newNode;      // 返回原来的头节点    return head;              }// 在指定位置插入节点Node* insertAtPosition(Node* head, int data, int position) {    // 创建新节点Node* newNode = (Node*)malloc(sizeof(Node));      newNode->data = data; // 如果插入位置为0,则将新节点作为新的头节点    if (position == 0) {        newNode->next = head;        return newNode;     }    Node* current = head;    // 找到插入位置的前一个节点    for (int i = 0; i next;    }// 将新节点的next指针指向当前位置的节点    newNode->next = current->next;      // 将当前位置的节点指向新节点current->next = newNode;            // 返回原来的头节点return head;                    }// 从链表开头删除节点Node* deleteAtBeginning(Node* head) {    if (head == NULL) {        printf("链表为空");        return NULL;    }    Node* temp = head;    // 更新头节点    head = head->next;      // 释放删除节点的内存    free(temp);  // 返回新的头节点           return head;        }// 从链表末尾删除节点Node* deleteAtEnd(Node* head) {    if (head == NULL) {        printf("链表为空!!!\n");        return NULL;    }// 如果只有一个节点,直接删除    if (head->next == NULL) {        free(head);           return NULL;    }    Node *current = head, *prev;    // 找到倒数第二个节点    while (current->next != NULL) {        prev = current;        current = current->next;    }//将倒数第二个节点的next指针设置为NULL,删除最后一个节点    prev->next = NULL;      // 释放删除节点的内存free(current);          // 返回原来的头节点return head;        }// 根据数据值删除节点Node* deleteByValue(Node* head, int data) {    if (head == NULL) {        printf("链表为空!!!\n");        return NULL;    }    Node *current = head, *prev;    // 遍历链表找到要删除的节点    while (current != NULL && current->data != data) {        prev = current;        current = current->next;    }    if (current == NULL) {        printf("数据不存在!!!\n");        return head;    }    if (current == head) {        //如果删除节点是头节点,则更新头节点head = head->next;      } else {    //将前一个节点的next指针跳过删除节点        prev->next = current->next;     }    free(current);// 释放删除节点的内存    return head;}//打印链表数据 void printList(Node* head) {    Node* current = head;    printf("链表所存数据: ");//表头为空,结束循环     while (current != NULL) {        printf("%d ", current->data);        current = current->next;    }    printf("\n");}//主函数 int main() {//创建链表     Node* head = createLinkedList();    printf("链表已经创建完成,可以正常使用!!!\n");while(true){printf("1、添加新的数据到链表头。\n"); printf("2、添加新的数据到链表尾。\n");printf("3、添加新的数据到固定位置。\n");printf("4、删除链表头的数据。\n");printf("5、删除链表尾的数据。\n");printf("6、删除指定数据。\n");printf("7、退出程序。\n");printf("请输入你的选择:");int ch;bool flag=false;scanf("%d",&ch);system("cls");switch(ch){case 1:int insertN;printf("请输入需要插入的数据:");scanf("%d",&insertN); head = insertAtBeginning(head, insertN);break;case 2:int insertEndN;printf("请输入需要插入的数据:");scanf("%d",&insertEndN);head = insertAtEnd(head, insertEndN);break;case 3:int insertPosN,pos;printf("请输入需要插入的数据和位置:");scanf("%d %d",&insertPosN,&pos);head = insertAtPosition(head, insertPosN, pos-1);break;case 4:head = deleteAtBeginning(head);break;case 5:head = deleteAtEnd(head);break;case 6:int delN;printf("请输入需要删除的数据:");scanf("%d",&delN); head = deleteByValue(head, delN);break;case 7:printf("程序结束,欢迎使用。\n");exit(0);default:printf("您的输入有误,请检查后重新输入!\n");flag=true;break;}if(!flag){printf("****-----------------------------****\n");printList(head);printf("****-----------------------------****\n\n");}getchar();}    return 0;}

上一篇:Win10安全模式一键进入,轻松解决系统安全难题!

下一篇:首选dns服务器怎么看?