1.什么是链表

  
链表是一种常见的数据结构。它与常见的数组是不同的,使用数组时先要指定数组包含元素的个数,即为数组的长度,但是如果向这个数组中加入的元素超过了数组的大小时,便不能将内容全部保存。
  链表这种存储方式,其元素个数是不受限定的,当进行添加元素的时候存储的个数就会随之改变。

在链表中有一个头指针,这个指针指向链表的第一个结点,每个结点包括两个部分:数据域和指针域,指针域存放下一个结点的地址,最后一个结点的指针域必须为NULL

2.设计链表

2.1 创建结点(结构体)
struct Node { int data; struct Node* next; };
2.2定义全局链表头尾指针方便调用
struct Node* head = NULL;//头指针 struct Node* end = NULL;//尾指针
2.3创建链表,实现在链表增加结点

法一:头插法

 
void AddList(int i)//头插法 { struct Node* tmp = (struct
Node*)malloc(sizeof(struct Node)); if (tmp == NULL) { return; } tmp->data = i;
//赋值 tmp->next = NULL; if (head == NULL) { head = tmp; end = tmp; } else {
tmp->next = head; head = tmp; } }
法二:尾插法

 
void AddList(int i)//尾插法 { struct Node* tmp = (struct
Node*)malloc(sizeof(struct Node)); if (tmp == NULL) { return; } tmp->data = i;
tmp->next = NULL; if (head == NULL) { head = tmp; end = tmp; } else { end->next
= tmp; end = tmp; } }
2.4查询指定的结点

这个直接上代码吧
struct Node* FindListNode(int i) { struct Node* tmp = head; while (tmp !=
NULL) { if (i == tmp->data) { return tmp; } tmp = tmp->next; } return NULL; }
2.5插入操作

 
void ListInsert(int i,int number)//在第i个位置之前插入number这个数据 { if (head ==
NULL||i<=1||i>MAX) { printf("无法插入\n"); return; } struct Node* tmp = (struct
Node*)malloc(sizeof(struct Node)); if (tmp == NULL) { return; } tmp->data
=number; struct Node* p = head; int j = 1; while (j < i-1) { p = p->next; j++;
} tmp->next = p->next; p->next = tmp; }
2.5删除尾结点
void ListDeleTail() { if (head == NULL)//判断是不是空链表 { printf("空链表\n"); return; }
if (head == end)//链表只有一个结点 { free(head); head = NULL; end = NULL; }
else//链表有多个结点 { struct Node* tmp = head; while (tmp->next != end) { tmp =
tmp->next;//找尾结点前一个结点 } free(end);//释放尾巴 end = tmp;//重新标记尾结点 end->next =
NULL;//将尾结点指针域置为空指针 } }

尾删除的过程首先应判断这个链表是不是为空或者只有一个节点,若只有一个节点则直接置NULL,若不为空,则先通过遍历找到倒数第二个节点,将最后一个节点释放内存,再将倒数第二个节点设置为end,然后将它的指针指向NULL。

2.6删除第一个结点
void ListDeleHead() { struct Node* tmp = head;//标记原来头的位置 if (head ==
NULL)//判断是否为空链表 { printf("空链表\n"); return; } head = head->next; free(tmp); tmp
= NULL; }
2.7删除指定的结点

 
void ListDele(int i) { if (head==NULL)//判断是不是空链表 { printf("空链表\n"); return; }
struct Node* tmp = FindListNode(i);//查找结点位置 if (tmp == NULL) { printf("查无\n");
return; } if (head == end)//链表只有一个结点 { free(head); head = NULL; end = NULL; }
else if (head->next==end)//链表有两个结点 { if (head == tmp)//判断删头还是尾 {
ListDeleHead(); } else if (end == tmp) { ListDeleTail(); } } else { if (head ==
tmp)//判断删头还是尾 { ListDeleHead(); } else if (end == tmp) { ListDeleTail(); } else
{ struct Node* p = head;//找要删除的前一个结点 while (p->next != tmp) { p = p->next; }
p->next = tmp->next; free(tmp); tmp = NULL; } } }
剩下的函数实现就没什么难的,下面上全部代码
#define _CRT_SECURE_NO_WARNINGS 1 #define MAX 10 #include<stdio.h>
#include<stdlib.h> #include<string.h> struct Node { int data; struct Node*
next; }; struct Node* head = NULL;//头指针 struct Node* end = NULL;//尾指针 //void
AddList(int i)//头插法 //{ // struct Node* tmp = (struct
Node*)malloc(sizeof(struct Node)); // if (tmp == NULL) //{ // return; //} //
tmp->data = i; //赋值 // tmp->next = NULL; // if (head == NULL) // { // head =
tmp; // end = tmp; // } // else // { // tmp->next = head; // head = tmp; // }
//} void AddList(int i)//尾插法 { struct Node* tmp = (struct
Node*)malloc(sizeof(struct Node)); if (tmp == NULL) { return; } tmp->data = i;
tmp->next = NULL; if (head == NULL) { head = tmp; end = tmp; } else { end->next
= tmp; end = tmp; } } void ListInsert(int i,int number)//在第i个位置之前插入number这个数据 {
if (head == NULL||i<=1||i>MAX) { printf("无法插入\n"); return; } struct Node* tmp =
(struct Node*)malloc(sizeof(struct Node)); if (tmp == NULL) { return; }
tmp->data =number; struct Node* p = head; int j = 1; while (j < i-1) { p =
p->next; j++; } tmp->next = p->next; p->next = tmp; } struct Node*
FindListNode(int i) { struct Node* tmp = head; while (tmp != NULL) { if (i ==
tmp->data) { return tmp; } tmp = tmp->next; } return NULL; } void
ListDeleHead() { struct Node* tmp = head;//标记原来头的位置 if (head == NULL)//判断是否为空链表
{ printf("空链表\n"); return; } head = head->next; free(tmp); tmp = NULL; } void
ListDeleTail() { if (head == NULL)//判断是不是空链表 { printf("空链表\n"); return; } if
(head == end)//链表只有一个结点 { free(head); head = NULL; end = NULL; } else//链表有多个结点
{ struct Node* tmp = head; while (tmp->next != end) { tmp =
tmp->next;//找尾结点前一个结点 } free(end);//释放尾巴 end = tmp;//重新标记尾结点 end->next =
NULL;//将尾结点指针域置为空指针 } } void ListDele(int i) { if (head==NULL)//判断是不是空链表 {
printf("空链表\n"); return; } struct Node* tmp = FindListNode(i);//查找结点位置 if (tmp
== NULL) { printf("查无\n"); return; } if (head == end)//链表只有一个结点 { free(head);
head = NULL; end = NULL; } else if (head->next==end)//链表有两个结点 { if (head ==
tmp)//判断删头还是尾 { ListDeleHead(); } else if (end == tmp) { ListDeleTail(); } }
else { if (head == tmp)//判断删头还是尾 { ListDeleHead(); } else if (end == tmp) {
ListDeleTail(); } else { struct Node* p = head;//找要删除的前一个结点 while (p->next !=
tmp) { p = p->next; } p->next = tmp->next; free(tmp); tmp = NULL; } } } void
ListPrint() { struct Node* tmp = head; while (tmp != NULL) { printf("%d\n",
tmp->data); tmp = tmp->next; } } void ListFree() { struct Node* tmp = head; if
(head == NULL) { printf("链表已空\n"); return; } while (tmp != NULL) { struct Node*
p = tmp; tmp = tmp->next; free(p); p = NULL; } head = NULL; end = NULL;
printf("清空成功\n"); } int main() { int i = 0; for (i = 0; i < MAX; i++)//创10个结点 {
AddList(i); } ListInsert(4,14);//在第4个位置之前插入14这个数据 struct Node* find; find =
FindListNode(4); if (find != NULL) { printf("找到%d\n", find->data); } else {
printf("没找到\n"); } ListDele(3);//删除第3个结点 ListPrint();//输出链表 ListFree();//删除整个链表
return 0; }

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信