一、链表概述
- 链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
- 与数组区别:
链表是链式的存储结构,数组是顺序的存储结构。
链表通过指针来连接元素与元素,数组则是把所有元素按次序依次存储。
优缺点如图:
二、创建链表前的准备工作
1.结点构成
- 数据域:存放用户需要的实际数据
- 指针域:存放下一个结点的地址
2.malloc函数
- 函数原型:void *malloc(unsigned int size);
- 功能:在内存的动态存储区申请一个长度为size字节的连续存储空间,并返回该存储空间的起始地址。如果没有足够的内存空间可分配,则函数的返回值为空指针NULL。
- 说明:这个函数返回的是个void类型指针,所以在使用时应注意强制类型转换成需要的指针类型。
3.free函数
- 函数原型:void free(void *p);
- 功能:将指针变量p指向的存储空间释放,交换给系统。
三、创建链表
1.尾插法
- 特点:输入顺序(存储顺序)与输出顺序相同
- 图解:
- 核心代码
end->next = p; //尾节点连接新节点
end = p; //尾节点向后移动成为新的尾节点
2.头插法
- 特点:输入顺序(存储顺序)与输出顺序相反
- 图解:
- 核心代码:
p->next = head->next; //新节点指向头节点的下一位
head->next = p; //头节点连接新节点
3.完整代码
struct node *creat() {
//定义头指针head,尾指针end,和指向新节点的指针p
struct node *head= NULL, *end = NULL, *p = NULL; //初始化
head = (struct node *)malloc(sizeof(strcut node)); //动态申请内存
end = head;
head->next = NULL;
p = (struct node *)malloc(sizeof(strcut node));
scanf("%d", &p->data);
while(p->data != 0) { //当输入的值为0时结束
//被注释掉的是头插法
//p->next = head ->next;
//head->next = p;
end->next = p;
p->next = NULL;
end = p;
//以上三行未注释是尾插法
p = (struct node *)malloc(sizeof(strcut node));
scanf("%d", &p->data);
}
free(p); //释放最后申请的空间
return head;
}
四、链表的基本操作
1.增
遍历链表找到需要插入的位置,操作指针插入新节点。
代码:
void add(struct node *head) {
struct node *p = NULL, *p0 = NULL; //定义p0为需增加的新节点
int a=0;
p = head;
printf("请输入增加在哪个数字的后面\n");
scanf("%d", &a);
while(p && p->data != a) { //遍历链表直至结点数据域为a 或p为NULL
p = p->next;
}
if(p != NULL) {
p0 = (struct node *)malloc(sizeof(struct node));
scanf("%d", &p0->data);
p0->next = p->next;
p->next = p0;
} else {
printf("未找到该数\n");
}
return;
}
2.删
遍历链表找到需要删除的结点,操作指针删除该节点。
代码:
void delete_(struct node *head) {
struct node *p = head, p0 = NULL;
int a = 0;
printf("输入需要删除的数字\n");
scanf("%d", &a);
while(p && p->data != a) { //遍历链表找到要删除的数 或 p为NULL
p0 = p; //保存当前指针的指向
p = p->next;
}
if(p !=NULL) {
p0->next = p->next;
} else {
printf("未找到该数\n");
}
return;
}
3.改
遍历链表找到需要修改的结点,修改其数据域
代码:
void modity_(struct node *head) {
struct node *p = head;
int a=0;
printf("请输入需要修改的数字\n");
scanf("%d", &a);
while(p && p->data != a) { //遍历链表直至p->data 等于需要修改的数字 或p为NULL
p = p->next;
}
if( p!= NULL) {
printf("修改为:");
scanf("%d", p->data);
} else {
printf("未找到该数\n");
}
return;
}
4.查
遍历链表直至找到需要查询的数据。
代码:
void search(struct node *head) {
struct node *p = head;
int a=0;
printf("请输入需要查询的数字\n");
scanf("%d", &a);
while(p && p->data != a) { //遍历链表直至p->data == a 或p为NULL
p = p->next;
}
if(p != NULL) {
printf("%d\n", p->data);
} else {
printf("未找到该数\n");
}
return;
}