链表的基本操作(增删改查)–C语言
一、概述
链表:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分:
- 存储数据元素的数据域(data)
- 存储下一个结点地址的指针域。(*next)
二、基本操作
1.增加节点:
先找到想要增加节点的位置(3),然后创建一个新节点(new)并初始化,然后让3的next指向new;让new的next指向4;这样就完成了增加节点。
2.删除节点:
先找到想要删除节点的前一个位置(2),然后让2的next指向4;然后释放节点3;这样就完成了删除节点。
3.查找节点:
先找到想要查找节点的位置(3),然后输出节点3的data;这样就完成了查找节点。
4.修改节点:
1.修改数值: 先找到想要修改节点的位置(3),然后修改节点3的data;这样就完成了修改节点的数值。
2.修改位置: 先找到想要修改节点的前一个位置(2),然后将2的next(3)赋给Node;然后将2的next指向4,然后找到修改节点的目的位置(4)。最后,将4的next指向node(3),这样就完成了修改节点的位置。
三、注意事项
Note:
链表中最后一个节点的next必须指向NULL.
四、代码实现
1、定义结构体类型:
typedef struct listnode
{
int data;//链表的数据域
listnode *next;//指向链表下一节点的指针域
}listnode;
typedef struct headnode
{
listnode *head;//指向链表的头节点
int sz;//当前链表有几个节点
}headnode;
2.判断节点的有效性
panduan:
int panduan(int a,headnode *head)
{
while (a > head->sz || a < 1)//判断添加位置的有效性
{
printf("超出链表范围,请重新输入:");
scanf("%d", &a);
}
return a;
}
3.创建链表:
creat:
void creat(headnode* head,int n)
{
listnode *end, *node;
head->head = (listnode *)malloc(sizeof(listnode));//申请一个头节点
end = head->head;//end=head,防止链表为空时,报错
for (int i = 0; i < n; i++)//for循环初始化各个节点
{
node = (listnode *)malloc(sizeof(listnode));
head->sz++;//增加一个节点sz++
printf("请输入第%d个节点的值:",i+1);
scanf("%d", &node->data);
end->next = node;
end = node;
}
end->next = NULL;//让最后一个节点的next指向空
}
4.增加节点:
add:
void add(headnode *head)//增加节点
{
int a = 0;
int n = 0;
listnode *h = head->head;//备份一个头指针
printf("请输入要增加在第几个节点的后面:");
scanf("%d", &a);
a=panduan(a, head);
printf("请输入要增加的数字:");
scanf("%d", &n);
for (int i = 0; i < a; i++)//找到要增加节点的位置
{
h = h->next;
}
listnode *node = (listnode *)malloc(sizeof(listnode));
head->sz++;//增加一个节点,sz++
node->next = h->next;
h->next = node;
node->data = n;
printf("增加成功!!!\n");
}
5.删除节点
del
void del(headnode *head)
{
int f = 0;
listnode *h = head->head;//备份一个头指针
printf("请输入要删除的节点位置:");
scanf("%d", &f);
f=panduan(f, head);
for (int i = 0; i < f - 1; i++)//找到要删除节点的前一个位置
{
h = h->next;
}
listnode *del = h->next;
h->next = h->next->next;
free(del);//释放删除的节点
del = NULL;
head->sz--;//删除一个节点sz--
printf("删除成功!!!\n");
}
6.查找节点
search
void search(headnode *head)
{
int s = 0;
listnode *h = head->head;
printf("请输入要查找的节点位置:");
scanf("%d", &s);
s=panduan(s, head);
for (int i = 0; i < s; i++)//找到要查找节点的位置
{
h = h->next;
}
printf("第%d个节点的数值是:%d\n", s,h->data);
}
7.修改节点
modify:
void data(headnode *head)//修改数值
{
int l = 0;
int u = 0;
listnode *h = head->head;
printf("请输入要修改的节点位置:");
scanf("%d", &l);
l=panduan(l, head);
printf("请输入修改后的数值:");
scanf("%d", &u);
for (int i = 0; i < l; i++)//找到要修改节点的位置
{
h = h->next;
}
h->data = u;
printf("修改成功!!!\n");
}
void adds(headnode *head)//修改地址
{
int l = 0;
int u = 0;
listnode *h = head->head;
listnode *h1 = head->head;
printf("请输入要修改的节点位置:");
scanf("%d", &l);
l=panduan(l, head);
printf("请输入修改后的节点位置:");
scanf("%d", &u);
u=panduan(u, head);
for (int i = 0; i < l - 1; i++)//找到要修改节点的前一个位置
{
h = h->next;
}
listnode *node = h->next;
h->next = h->next->next;
for (int j = 0; j < u-1; j++)//找到要修改节点的目的位置
{
h1 = h1->next;
}
node->next = h1->next;
h1->next = node;
printf("修改成功!!!\n");
}
void modify(headnode *head)
{
int p = 0;
printf("1.修改数值 2.修改位置\n");
scanf("%d", &p);
while (p !=1 && p !=2 )//判断位置的有效性
{
printf("输入错误,请重新输入:");
scanf("%d", &p);
}
switch (p)
{
case 1:
data(head);
break;
case 2:
adds(head);
break;
default:
break;
}
}
8.打印链表
show:
void show(headnode *head)
{
listnode *h = head->head;
while (h->next != NULL)//打印链表
{
h = h->next;
printf("%d ", h->data);
}
printf("\n");
)
9.释放内存
destroy
void destroy(headnode *head)
{
free(head->head);
head->head = NULL;
}
10.菜单
menu:
void menu()
{
printf("*******1.创建链表 2.增加节点********\n");
printf("*******3.删除节点 4.查找节点********\n");
printf("*******5.修改链表 6.展示链表********\n");
printf("******* 0.exit ********\n");
}
11.主函数
main:
int main()
{
int n = 0;
headnode head = {0};//创建一个headnode类型的head
int intput = 0;
do
{
menu();
printf("请输入选择:");
scanf("%d", &intput);
getchar();
switch (intput)
{
case 1:
printf("请输入链表的个数:");
scanf("%d", &n);
creat(&head,n);
break;
case 2:
add(&head);
break;
case 3:
del(&head);
break;
case 4:
search(&head);
break;
case 5:
modify(&head);
break;
case 6:
show(&head);
break;
case 0:
destroy(&head);
printf("退出\n");
break;
default:
printf("选择错误,请重新输入!\n");
break;
}
} while (intput);
return 0;
}