链表的使用
- 什么是链表
链表是一种常见的数据结构。是动态进行储存分配·的一种结构。链表有一个“头指针”变量,它存放·一个地址,该地址指向一个元素。链表中每一个元素称为“结点”,每个结点包含两个部分:(1)用户需要的数据(2)下一个节点地址。
因为链表中各结点在内存中的地址可以是不连续的。所以需要用链表将各个元素连起来。即:头指针指向下一个元素,下一个元素再指向它下面的元素,以此类推。
所以要找某一个元素,必须先找到它的上一个元素,根据它提供的下一个元素地址才能找到下一个元素。
所以一个链表的头指针是十分重要的,不提供头指针连整个链表都无法打开。
在使用链表的时候,尽量不要对头指针直接使用,以防止头指针出现错误,造成链表错误。
2.创建链表
一般创建链表我们都用结构体 typedef struct
struct Student {
int id;
struct Student *next;
};
创建初始化链表
注意事项:
每定义一个结点,都要为其开辟空间,可用malloc,需添加头文件#include <stdlib.h>
初始化结点时,为防止出现野指针,先将下一个地址指向NULL
为防止直接对头结点进行操作,造成头结点损坏,重新定义一个结点使其等于头结点
初始化完成后将各个结点连接,并用新定义的结点等于下一个结点,防止数据改变
void chuanj(struct Student **head) {
struct Student *tail;
struct Student *node;
struct Student *node1;
//每定义一个结点,都要为其开辟空间,添加头文件#include <stdlib.h>
*head =(struct Student *)malloc(sizeof(struct Student));
(*head)->id = 1;
//初始化时,为防止出现野指针,先将下一个地址指向NULL
(*head)->next = NULL;
//为防止直接对头结点进行操作,造成头结点损坏,重新定义一个结点使其等于头结点
tail = *head;
node =(struct Student *)malloc(sizeof(struct Student));
node->id = 2;
node->next = NULL;
//开辟128字节空间
node1 = malloc(128);
node1->id = 3;
node1->next = NULL;
//初始化完成后将各个结点连接,并用新定义的结点等于下一个结点,防止数据改变
tail->next = node;
tail = node;
tail->next = node1;
tail = node1;
node1->next = NULL;
}
- 删除链表结点
删除一个结点,需要找到其上一个结点
假设需要删除id为2的结点,需要找到指向该结点的结点
即:p->next->id == 2
新建一个结点q,使q等于要删除的结点
即:q = p->next
将需要删除的结点上一个结点和其下一个结点相连接,完成删除
即: p->next = q->next;
void shanchu(struct Student *ptem) {
struct Student *p = ptem;
struct Student *q;
while (p != NULL && p->next != NULL) {
if (p->next->id == 2) {
q = p->next;
p->next = q->next;
break;
}
p = p->next;
}
free(q);//删除完将其释放
}
- 添加链表结点
假设需要在id为3的结点前添加结点,同样需要找到id=3的上一个结点p
即:p->next->id == 3
新建一个结点q,q为需要添加的结点,首先先对其初始化
即: q = (struct Student *)malloc(sizeof(struct Student));
q->next = NULL;
q->id = 5;
将新建结点指向id=3的结点
即: q->next = p->next;
再将原本指向id=3的结点指向新建的结点
即: p->next = q;
注:如果先将原本指向id=3的结点指向新建的结点,会造成后面链表断掉。顺序不可以颠倒
void tianjia(struct Student *tmp) {
struct Student *p = tmp;
struct Student *q;
q = (struct Student *)malloc(sizeof(struct Student));
q->next = NULL;
q->id = 5;
while (p != NULL && p->next != NULL) {
if (p->next->id == 3) {
q->next = p->next;
p->next = q;
break;
}
p = p->next;
}
}
- 遍历输出链表
void printinit(struct Student *stu) {
struct Student *p = stu;
while (p != NULL) {
printf("%d\n", p->id);
p = p->next;
}
}