一、链表的插入
1.1.尾插法
尾插法指在链表中特定节点的后面插入一个节点。insertFromBehide
函数有三个参数,分别是struct Test *head
把原来的链表首地址传过来,int data
在这个数据的后面插入,struct Test *new
插入这一个新的节点。
#include <stdio.h>
struct Test
{
int data;
struct Test *next;
};
void printLink(struct Test *head)
{
struct Test *point;
point= head; //使用指针更方便看
while(point != NULL){ //判断指针的指向是否为NULL,为NULL就结束
printf("%d ",point->data); //输出结构体的数据
point= point->next; //输出结束之后,指针指向下一个,也就是下一个结构体的首地址
}
puts("\n");
}
int insertFromBehide(struct Test *head, int data, struct Test *new)
{
struct Test *point = head;
while(point != NULL){
if(point->data == data){
//这两个位置不能交换,如果交换了,新节点的尾只能指向NULL
new->next = point->next; //先把新节点的尾巴接到data的下一个节点的头
point->next = new; //再让data原先指向下一个的指针,指向新节点的头
return 1;
}
point = point->next;
}
return 0;
}
int main()
{
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
struct Test new = {100,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
int data,result;
printf("Please input which data you want to insert behind:\n");
scanf("%d",&data);
result = insertFromBehide(&t1,data,&new);
if(result == 1){
printLink(&t1);
}
if(result == 0){
printf("ERROR!\n");
}
return 0;
}
2.2.头插法
头插法有两种情况:
- 在链表的表头插入一个新的节点
- 在链表中间,特定节点的前面插入一个新节点
#include <stdio.h>
struct Test
{
int data;
struct Test *next;
};
void printLink(struct Test *head)
{
struct Test *point;
point= head; //使用指针更方便看
while(point != NULL){ //判断指针的指向是否为NULL,为NULL就结束
printf("%d ",point->data); //输出结构体的数据
point= point->next; //输出结束之后,指针指向下一个,也就是下一个结构体的首地址
}
puts("\n");
}
struct Test *insertFromAhead(struct Test *head, int data, struct Test *new)
{
struct Test *point = head;
if(point->data == data){ //在该链表的头插入
new->next = point; //把新节点的尾巴接到链表的头
return new; //返回新链表的新头
}
while(point->next != NULL){ //这里为什么不像之前一样是(point != NULL)呢?因为上面代码已经交代了要是在链表头插入的情况了,因此,这里要在第二个开始遍历
if(point->next->data == data){ //point->next->data指的是下一个节点的数据
new->next = point->next; //这里的point->next是指下一个节点的头,把新节点的尾巴接到下一个节点的头
point->next = new; //这里的point->next是指当前节点的尾巴接到新节点的头
return head; //如果成功找到该节点并且成功插入,就把该链表的头返回出去
}
point = point->next;
}
printf("Haven't this data%d\n",data); //如果没有该节点,则打印这句话
return head;
}
int main()
{
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
struct Test new = {100,NULL};
struct Test *head = NULL;
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
printf("Please input which data you want to insert in front of:\n");
scanf("%d",&data);
head = insertFromAhead(&t1, data, &new);
printLink(head);
return 0;
}
二、链表的删除
链表删除指定节点有两种情况:
- 删除头节点
- 删除中间节点
#include <stdio.h>
struct Test
{
int data;
struct Test *next;
};
void printLink(struct Test *head)
{
struct Test *point;
point= head; //使用指针更方便看
while(point != NULL){ //判断指针的指向是否为NULL,为NULL就结束
printf("%d ",point->data); //输出结构体的数据
point= point->next; //输出结束之后,指针指向下一个,也就是下一个结构体的首地址
}
puts("\n");
}
struct Test *deleteNode(struct Test *head, int data)
{
struct Test *point = head;
if(point->data == data){ //如果删除头节点
return point->next; //把第二个节点当作头节点返回去
}
while(point->next != NULL){
if(point->next->data == data){
point->next = point->next->next; //让当前节点的尾巴,指向下下个节点的头,也就是被删除节点的尾巴
return head;
}
point = point->next;
}
printf("There is no this data%d!\n",data);
return head;
}
int main()
{
struct Test *p = NULL;
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
struct Test t4 = {4,NULL};
struct Test t5 = {5,NULL};
struct Test t6 = {6,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
printf("Please input which data you want to delete:\n");
scanf("%d",&data);
p = deleteNode(&t1,data);
printLink(p);
return 0;
}
三、链表的修改
在查找的基础上只是添加了这一行代码即可实现point->data = newData;
。
int changeLink(struct Test *head, int data, int newData)
{
struct Test *point = head;
while(point != NULL){
if(point->data == data){ //与链表里的值做对比
point->data = newData; //让之前的数据直接变成新数据
return 1;
}
point = point->next; //指针指向下一个首地址
}
return 0;
}
四、动态创建链表
4.1.头插法
每来一次新的数据,就放在链表的头里,先到后出,类似栈,也类似弹匣压子弹的方式。
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test *next;
};
void printLink(struct Test *head)
{
struct Test *point;
point= head; //使用指针更方便看
while(point != NULL){ //判断指针的指向是否为NULL,为NULL就结束
printf("%d ",point->data); //输出结构体的数据
point= point->next; //输出结束之后,指针指向下一个,也就是下一个结构体的首地址
}
puts("\n");
}
struct Test *insertFromHead(struct Test *head, struct Test *new)
{
if(head == NULL){ //如果指向NULL的话,直接让最新的节点变成表头
head = new;
}else{
new->next = head; //如果不是就把新节点的尾巴接到链表的头
head = new; //新的节点就变成链表的头
}
return head;
}
struct Test *createLink(struct Test *head)
{
struct Test *new;
while(1){
new = (struct Test *)malloc(sizeof(struct Test));
printf("Please input your node:\n");
scanf("%d",&(new->data));
if(new->data == 0){
printf("quit\n");
free(new);
return head; //输入0结束后,把链表的头返回出去
}
head = insertFromHead(head, new);
}
}
int main()
{
struct Test *head = NULL;
struct Test t1 = {999,NULL};
head = createLink(head);
printLink(head);
head = insertFromHead(head,&t1);
printLink(head); //在链表头插入t1之后
return 0;
}
4.2.尾插法
尾插法讲究先来后出,按顺序输入,按顺序输出。
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test *next;
};
void printLink(struct Test *head)
{
struct Test *point;
point= head; //使用指针更方便看
while(point != NULL){ //判断指针的指向是否为NULL,为NULL就结束
printf("%d ",point->data); //输出结构体的数据
point= point->next; //输出结束之后,指针指向下一个,也就是下一个结构体的首地址
}
puts("\n");
}
struct Test *insertFromBehind(struct Test *head, struct Test *new)
{
struct Test *point = head;
if(point == NULL){
head = new; //如果指向NULL,直接返回链表头
return head;
}
while(point->next != NULL){
point = point->next;
}
point->next = new; //如果是在最后一个数据插入,new的头接在最后一个节点
return head;
}
struct Test *createLink(struct Test *head)
{
struct Test *new;
while(1){
new = (struct Test *)malloc(sizeof(struct Test));
printf("Please input your node:\n");
scanf("%d",&(new->data));
if(new->data == 0){
printf("quit\n");
free(new);
return head; //输入0结束后,把链表的头返回出去
}
head = insertFromBehind(head, new);
}
}
int main()
{
struct Test *head = NULL;
struct Test t1 = {999,NULL};
head = createLink(head);
printLink(head);
head = insertFromBehind(head,&t1);
printLink(head); //在链表最后插入t1
return 0;
}