赞
踩
链表的概念及结构
概念:基于数组的缺点,数据结构中诞生了新的结构就是 链表
当一组数据需要频繁的进行插入、删除操作时候,链表则是首选的数据结构
链表也属于 线性表
链表由结点组成
结点分为两部分:
数据域,保存存储的数据元素
指针域,指向下一个结点的地址
注:链表也属于线性表,拥有线性表的所有特点
- struct Node{
- int data; //数据域
- struct Node *next; //指针域
- };
实现单向链表,能够存放整型数据,设计需求如下:
链表的初始化
获取链表长度
插入指定位置结点
删除指定位置结点
清空链表
释放链表
- typedef struct node
- {
- int data;//数据域
- struct node* next; //指针域
- }Node, *LinkList; //Node是struct node的别名, LinkList 代表struct node*数据类型
-
- //链表的初始化
- LinkList creat_list()
- {
- LinkList head = (Node *)malloc(sizeof(Node));
- if (!head)
- {
- printf("内存分配失败\n");
- return NULL;
- }
-
- head->next = NULL; //带头结点的链表,只维护指针域,无需维护数据域
-
- return head;
- }
功能:
创建一个链表的头结点,并返回给使用者
- //统计链表长度
- int size_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return 0;
- }
- Node * pCur = head->next; //获取第一个有数据的结点
-
- int num = 0;
- while (pCur != NULL)
- {
- num++;
- pCur = pCur->next;
- }
- return num;
- }
功能:
统计链表中结点的个数并返回
- //插入结点 参数1 链表的头结点 参数2 插入位置 参数3 插入数据
- void insert_list(LinkList head, int pos , int val)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- if (pos < 0 || pos > size_list(head))
- {
- printf("插入位置无效\n");
- return;
- }
-
- //辅助指针,帮助我们找到待插入位置的前驱结点
- Node* pCur = head;
- for (int i = 0; i < pos; i++)
- {
- pCur = pCur->next;
- }
-
- //创建新结点
- Node* newNode = (Node *)malloc(sizeof( Node));
- if (!newNode)
- {
- return;
- }
- newNode->data = val;
- newNode->next = NULL;
-
- //将新结点插入到链表长
- newNode->next = pCur->next;
- pCur->next = newNode;
- }
功能:
向指定的位置上,插入新的结点
- //遍历链表
- void foreach_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- Node* pCur = head->next; //拿到第一个有数据的结点
-
- while (pCur != NULL)
- {
- printf("%d ", pCur->data);
- pCur = pCur->next;
- }
- printf("\n");
- }
功能:
打印链表中每个结点的数据域
- //删除结点 参数1 链表表头 参数2 删除位置
- void delete_list(LinkList head, int pos)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- if (pos < 0 || pos > size_list(head) - 1)
- {
-
- printf("删除位置无效\n");
- return;
- }
-
- //辅助指针,帮助我们找到待删除位置的前驱结点
- Node* pCur = head;
- for (int i = 0; i < pos; i++)
- {
- pCur = pCur->next;
- }
- //记录待删除结点
- Node* pDel = pCur->next;
- //更改指针,删除结点
- pCur->next = pDel->next;
- //释放待删除的结点
- free(pDel);
- }
功能:
删除指定位置上的结点
- //清空链表
- void clear_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- //指向第一个有数据的结点
- Node * pCur = head->next;
-
- while (pCur != NULL)
- {
- //先保存住下一个节点的位置
- Node * pNext = pCur->next;
-
- //释放节点
- free(pCur);
- pCur = pNext;
- }
-
- head->next = NULL;
-
- }
功能:
删除指定位置上的结点
- //销毁链表
- void destroy_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- //先清空链表
- clear_list(head);
-
- //将头结点也释放掉,完成整个链表的销毁
- free(head);
- head = NULL;
- }
功能:
删除指定位置上的结点
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<string.h>
- #include<stdlib.h>
-
- typedef struct node
- {
- int data;//数据域
- struct node* next; //指针域
- }Node, *LinkList; //Node是struct node的别名, LinkList 代表struct node*数据类型
-
- //链表的初始化
- LinkList creat_list()
- {
- LinkList head = (Node *)malloc(sizeof(Node));
- if (!head)
- {
- printf("内存分配失败\n");
- return NULL;
- }
-
- head->next = NULL; //带头结点的链表,只维护指针域,无需维护数据域
-
- return head;
- }
-
- //统计链表长度
- int size_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return 0;
- }
- Node * pCur = head->next; //获取第一个有数据的结点
-
- int num = 0;
- while (pCur != NULL)
- {
- num++;
- pCur = pCur->next;
- }
- return num;
- }
-
- //插入结点 参数1 链表的头结点 参数2 插入位置 参数3 插入数据
- void insert_list(LinkList head, int pos , int val)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- if (pos < 0 || pos > size_list(head))
- {
- printf("插入位置无效\n");
- return;
- }
-
- //辅助指针,帮助我们找到待插入位置的前驱结点
- Node* pCur = head;
- for (int i = 0; i < pos; i++)
- {
- pCur = pCur->next;
- }
-
- //创建新结点
- Node* newNode = (Node *)malloc(sizeof( Node));
- if (!newNode)
- {
- return;
- }
- newNode->data = val;
- newNode->next = NULL;
-
- //将新结点插入到链表长
- newNode->next = pCur->next;
- pCur->next = newNode;
- }
-
-
- //遍历链表
- void foreach_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- Node* pCur = head->next; //拿到第一个有数据的结点
-
- while (pCur != NULL)
- {
- printf("%d ", pCur->data);
- pCur = pCur->next;
- }
- printf("\n");
- }
-
-
- //删除结点 参数1 链表表头 参数2 删除位置
- void delete_list(LinkList head, int pos)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- if (pos < 0 || pos > size_list(head) - 1)
- {
-
- printf("删除位置无效\n");
- return;
- }
-
- //辅助指针,帮助我们找到待删除位置的前驱结点
- Node* pCur = head;
- for (int i = 0; i < pos; i++)
- {
- pCur = pCur->next;
- }
- //记录待删除结点
- Node* pDel = pCur->next;
- //更改指针,删除结点
- pCur->next = pDel->next;
- //释放待删除的结点
- free(pDel);
- }
-
- //清空链表
- void clear_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- //指向第一个有数据的结点
- Node * pCur = head->next;
-
- while (pCur != NULL)
- {
- //先保存住下一个节点的位置
- Node * pNext = pCur->next;
-
- //释放节点
- free(pCur);
- pCur = pNext;
- }
-
- head->next = NULL;
-
- }
-
-
- //销毁链表
- void destroy_list(LinkList head)
- {
- if (head == NULL)
- {
- printf("传入链表为空\n");
- return;
- }
-
- //先清空链表
- clear_list(head);
-
- //将头结点也释放掉,完成整个链表的销毁
- free(head);
- head = NULL;
- }
- int main() {
-
- LinkList head = creat_list(); //创建链表,获取表头
-
- //打印链表长度
- printf("链表长度为:%d\n", size_list(head));
-
- //插入结点
- insert_list(head, 0, 10);
- insert_list(head, 0, 20);
- insert_list(head, 1, 30);
- insert_list(head, 0, 40);
-
- //遍历链表
- printf("插入结点后,遍历结果为:\n"); // 40 20 30 10
- foreach_list(head);
-
- //打印链表长度
- printf("链表长度为:%d\n", size_list(head));
-
- //删除结点
- delete_list(head, 2);
- printf("删除结点后,遍历结果为:\n"); // 40 20 10
- foreach_list(head);
-
- //清空链表
- clear_list(head);
- printf("清空链表后,遍历结果为:\n");
- foreach_list(head);
-
- //销毁链表
- destroy_list(head);
-
- system("pause");
- return EXIT_SUCCESS;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。