1、为什么要使用链表
对于数据的处理,增删改查会减少工作量
2、链表与数组的区别与实现
(:set nu):显示行号
代码实现:
#include <stdio.h>
//结构体初始化
//第一个元素为整型
//第二个为名叫next的指针,指向结构体本身
struct Test
{
int data;
struct Test *next;
};
int main()
{
//实例化3个结构体
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
//t1的指针指向结构体t2
t1.next = &t2;
//t2的指针指向结构体t3
t2.next = &t3;
printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);
}
3、链表静态添加与动态遍历
//遍历链表的方法
void printLink(struct Test *head)
{
//定义一个结构体型指针
struct Test *point;
//指向head
point = head;
//当point不为空时,说明还没到最后一个
//打印当前数据
//打印完成后,point再指向下一个结构体
while(point != NULL)
{
printf("%d",point->data);
point = point->next;
}
}
完整代码:
#include <stdio.h>
//结构体初始化
//第一个元素为整型
//第二个为名叫next的指针,指向结构体本身
struct Test
{
int data;
struct Test *next;
};
//遍历链表的方法
void printLink(struct Test *head)
{
//定义一个结构体型指针
struct Test *point;
//指向head
point = head;
//当point不为空时,说明还没到最后一个
//打印当前数据
//打印完成后,point再指向下一个结构体
while(point != NULL)
{
printf("%d",point->data);
point = point->next;
}
}
int main()
{
//实例化3个结构体
struct Test t1 = {1,NULL};
struct Test t2 = {2,NULL};
struct Test t3 = {3,NULL};
//t1的指针指向结构体t2
t1.next = &t2;
//t2的指针指向结构体t3
t2.next = &t3;
printLink(&t1);
//printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);
}
4、统计链表节点个数及链表查找
//获取链表节点数
int getLinkNum(struct Test *head)
{
int num = 0;
while(head != NULL)
{
num++;
head = head->next;
}
return num;
}
int main()
{
int a = getLinkNum(&t1);
printf("%d",a);
}
//链表查找
int searchLink(struct Test *head,int data)
{
while(head != NULL)
{
if(head->data == data)
{
return 1;
}
head = head->next;
}
return 0;
}
5、链表从指定节点后方插入新的节点
//链表插入
void insertLink(struct Test *head,int data,struct Test *new)
{
struct Test *p = head;
while(p!= NULL)
{
if(p->data == data)
{
new->next = p->next;
p->next = new;
}
p = p->next;
}
}
int main()
{
//创建新的结构体
struct Test new = {99,NULL};
insertLink(&t1,3,&new);
}
6、链表从指定节点前方插入新的节点
两种情况:
①在head前插入
②在不是head前插入
#include <stdio.h>
struct Test
{
int data;
struct Test *next;
};
//遍历链表的方法
void printLink(struct Test *head)
{
struct Test *point;
point = head;
//当point不为空时,说明还没到最后一个,打印当前数据,打印完成后,point再指向下一个结构体
while(point != NULL)
{
printf("%d ",point->data);
point = point->next;
}
}
//在data前方插入new
//第一种在head前面插入,但是插入方法里面的head是局部变量,main里面的head不变,所以写一个指针函数获取插入后的head
struct Test *insertFrom(struct Test *head,int data,struct Test *new)
{
struct Test *p = head;
if(p->data == data)
{
new->next = head;
return new;
}
//第二种,在非首项前插入
while(p->next != NULL)
{
if(p->next->data == data)
{
new->next = p->next;
p->next = new;
return head;
}
p = p->next;
}
}
int main()
{
//实例化3个结构体
struct Test t1 = {5,NULL};
struct Test t2 = {56,NULL};
struct Test t3 = {3,NULL};
//t1的指针指向结构体t2
t1.next = &t2;
//t2的指针指向结构体t3
t2.next = &t3;
struct Test *head = &t1;
struct Test new = {99,NULL};
head = insertFrom(head,56,&new);
printLink(head);
}
7、链表删除指定节点
两种情况:
①删除head,改head
②删除非head
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test *next;
};
//遍历链表的方法
void printLink(struct Test *head)
{
struct Test *point;
point = head;
//当point不为空时,说明还没到最后一个,打印当前数据,打印完成后,point再指向下一个结构体
while(point != NULL)
{
printf("%d ",point->data);
point = point->next;
}
}
//删除
struct Test *deleatLink(struct Test *head,int data)
{
struct Test *p = head;
//第一种删除首项
if(p->data == data)
{
head = p->next;
free(p);
return head;
}
//第二种,删除非首项
while(p->next != NULL)
{
if(p->next->data == data)
{
p->next = p->next->next;
return head;
}
p = p->next;
}
}
int main()
{
//实例化3个结构体
struct Test t1 = {5,NULL};
struct Test t2 = {56,NULL};
struct Test t3 = {3,NULL};
//t1的指针指向结构体t2
t1.next = &t2;
//t2的指针指向结构体t3
t2.next = &t3;
struct Test *head = &t1;
head = deleatLink(head,3);
printLink(head);
}
8、链表动态创建之头插法
新节点作为头
#include <stdio.h>
#include <stdlib.h>
struct Test
{
int data;
struct Test *next;
};
//遍历链表的方法
void printLink(struct Test *head)
{
struct Test *point;
point = head;
//当point不为空时,说明还没到最后一个,打印当前数据,打印完成后,point再指向下一个结构体
while(point != NULL)
{
printf("%d ",point->data);
point = point->next;
}
}
//动态创建头插法
struct Test *insertFromHead(struct Test *head)
{
struct Test *new;
new = (struct Test *)malloc(sizeof(struct Test));
new->next=NULL;//!!!开辟内存后指针要指空,否则为野指针
printf("请输入你的链表数据:");
scanf("%d",&(new->data));
if(head == NULL)
{
head = new;
return head;
}
else
{
new->next = head;
head = new;
return head;
}
}
int main()
{
//你的链表数据个数
int i = 6;
struct Test *head = NULL;
while(i--)
{
head = insertFromHead(head);
}
printLink(head);
return 0;
}
9、链表动态创建之尾插法
新节点作为尾