一、单向链表
节点中只包含一个指针,用来指向相邻节点
1. 创建节点
//设计节点
typedef struct node
{
int data; //数据域
struct node * next; //指针域
}Node , *Plist;
定义一个名为node的结构体,用于表示链表的节点。结构体中包含两个成员:整型变量data作为数据域,存储节点数据;一个指向 node 类型结构体的指针next作为指针域,指向下一个节点。Node和Plist是别名 分别表示 struct node 和 struct node* 类型。
2. 初始化一个 空链表 (带头的)
//初始化空链表
Plist Init_list()
{
Plist head = malloc(sizeof(Node));
if(NULL == head)
{
perror("malloc");
return NULL;
}
head->next = NULL;
return head;
}
创建并返回一个空 链表头(头节点)。链表头是链表的起始节点,指向链表第一个元素。使用malloc() 函数为 链表头分配内存空间,分配失败输出错误信息(#include <errno.h>)返回NULL。将链表头部的 next指针 指向NULL,表示链表目前是空的。函数返回链表头的指针。
sizeof(Node) //struct node的别名
(不带头):Plist head = NULL;
3. 新建节点
//创建节点
Plist Init_node(int data)
{
Plist head = malloc(sizeof(Node));
if(NULL == head)
{
perror("malloc");
return NULL;
}
head->next = NULL;
head->data = data;
return head;
}
多了一个 data 而已;
4. 插入节点
//插入节点--后插 node后面
void Insert_node_back(Plist new , Plist node)
{
new->next = node->next; //把new 和 node 后面的连接
node->next = new;
}
//插入节点--前插
void Insert_node_front(Plist new , Plist node , Plist head)
{
Plist prve = head;//定义 prev 为头节点
while(prve->next != node)//寻找目标节点
prve = prve->next;
Insert_node_back(new , prve);
}
//插入节点--头插
void Insert_node_head(Plist new , Plist head)
{
new->next = head->next;//连接
head->next = new;
}
//插入节点--尾插
void Insert_node_back(Plist new , Plist node)
{
Plist temp = head;
while(temp->next != NULL)//没到 尾巴
temp = temp->next;
new->next = NULL;
temp->next = new;
}
刚开始没理解前插 和 后插 哪里是前 哪里是后 next后 pre前面;
在链表的数据结构中,即使是空链表,通常也会有一个头节点。头节点是链表的起始点,即使链表中没有其他节点,头节点也是存在的。它的作用是为了简化对链表的操作,比如插入和删除节点时,从头节点开始处理更加方便;
5. 移除节点
void del_node(Plist head ,Plist node)
{
//空链表
if(Empty_list(head))
return;
//找到目标节点的上一个节点prev
Plist prev = head;
while (prev)
{
if(prev->next == node)
{
//让prev的next指向目标节点的下个节点
prev->next = node->next;
// prev->next = prev->next->next;
//断开目标节点
node->next = NULL;
break;
}
prev = prev->next;
}
}
node前 指 node下一个; node-> null ;
6. 查找
Plist find_node(Plist head ,int data)
{
//空链表
if(Empty_list(head))
return NULL;
Plist temp = head->next;
while (temp)//只要不为空
{
if(temp->data == data) //找到
return temp;
temp = temp->next;
}
return NULL;
}
7. 移动节点
//移动节点
void move_node(Plist head ,Plist node , Plist dest)
{
if(NULL == head || node == NULL || dest==NULL)
return;
del_node(head , node);
Insert_node(node , dest);
}
8. 遍历链表
void show_list(Plist head)
{
//空链表
if(Empty_list(head))
return;
Plist temp = head->next;
while (temp)
{
printf("%d->" , temp->data);
temp = temp->next;
}
printf("\n");
}
9. 判断是否为空链表
//判断是否是空链表 true:空链表 false:非空
bool Empty_list(Plist head)
{
return head->next == NULL;
}
10. 销毁链表
//销毁链表
void rm_list(Plist head)
{
if(NULL == head)
return;
Plist temp,node;
node = head;
while (1)
{
temp = node->next;//头的下一个
free(node);//
node = temp;//向后移动一位
if(temp == NULL)
break;
}
printf("销毁成功\n");
}
二、单向循环链表
1. 初始化链表
//初始化链表
Plist Init_list()
{
Plist head = malloc(sizeof(Node));
if(NULL == head)
{
perror("malloc");
return NULL;
}
head->next = head;
return head;
}
自己指向自己
2. 新建节点
//创建节点
Plist Init_node(int data)
{
Plist head = malloc(sizeof(Node));
if(NULL == head)
{
perror("malloc");
return NULL;
}
head->next = head;
head->data = data;
return head;
}
3. 判断链表是否为空
4. 遍历链表
//遍历链表
void show_list(Plist head)
{
if(NULL == head||Empty_list(head))
return;
Plist temp = head->next;
while (temp!=head)
{
printf("%d->",temp->data);
temp = temp->next;
}
printf("\n");
}
片段循环完毕 temp!=head
5. 寻找节点
//查找节点
Plist find_node(Plist head ,int data)
{
//空链表
if(Empty_list(head))
return NULL;
Plist temp = head->next;
while (temp != head)
{
if(temp->data == data)
return temp;
temp = temp->next;
}
return NULL;
}
6. 销毁链表
//销毁链表
void rm_list(Plist head)
{
if(NULL == head)
return;
Plist temp , node;
node = head->next;
temp = node->next;
while (temp != head)
{
temp = node->next;
del_node(head ,node);
free(node);
node = temp;
}
free(head);
head =NULL;
printf("销毁成功\n");
}
head指向NULL