双向链表【C语言】
写在前面的话:
- 编译器:DevC++
- 文本编辑器:Sublime Text3
- 本章内容:双向链表的使用
1.效果截图
2.全部代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct node //节点
{
int data; //数据域 也是可以有很多
struct node *prev; //前指针
struct node *next;//后指针
};
//初始化链表
struct node *init_list()
{
struct node *head = malloc(sizeof(struct node));//申请空间
if (head != NULL)
{
head->prev = head; //指针指向自己
head->next = head;
}
return head;
}
//创建新节点 和单链表就多了一个前指针而已
struct node *create_new_node(int m)
{
struct node *newNode = malloc(sizeof(struct node));//申请空间
//申请空间成功
if (newNode != NULL)
{
newNode->prev = newNode; //指针指向自己
newNode->next = newNode;
newNode->data = m;//将参数m赋值给结构体中的data
}
return newNode;
}
//尾插法,找到最后一个节点进行插入
void insert_node(struct node *head,struct node *newNode)
{
struct node *p = head;
while(p->next != head)//遍历到下一个节点是头节点,此时就是链表当中最后一个节点
{
p = p->next;//一直遍历下一个节点
}
newNode->next = p->next; //新指针next指向头
newNode->prev = p;//新指针prev指向最后一个节点
p->next->prev = newNode;//头指针的前指针指向新节点
p->next = newNode;//最后一个节点的next指针指向新节点
}
//将链表打印出来
void showlist(struct node *head)
{
struct node *p = head->next;//定义一个指针指向首节点(第一个节点)
printf("[链表]");
while(p != head)//当节点等于头节点,说明已经遍历完整个链表了,退出循环
{
printf("%d ",p->data );//将节点的数据打印出来
p = p->next;//遍历下一个节点
}
printf("\n");
}
//判断参数m是否存在于链表当中
bool exist(struct node *head,int m)
{
struct node *p = head->next;//定义一个指针指向首节点(第一个节点)
while(p != head)//当节点等于头节点,说明已经遍历完整个链表了,退出循环
{
if (p->data == m)//如果在链表中,查询到参数m,执行以下语句
{
printf("该节点已经存在\n");
return true;//存在于链表当中,返回true
}
p = p->next;//遍历下一个节点
}
return false;//不存在于链表当中,返回false
}
struct node * delete_node(struct node *head,int n)
{
struct node *p = head->next;//定义一个指针指向首节点(第一个节点)
while(p != head)//当节点等于头节点,说明已经遍历完整个链表了,退出循环
{
if (p->data == n) //p指向的是我想删除的节点
{
p->prev->next = p->next;//由p节点的前一个节点的next指针指向p节点的后一个节点
p->next->prev = p->prev;//由p节点的后一个节点的prev指针指向p节点的前一个节点
return p;
}
p = p->next;//遍历下一个节点
}
printf("没找到该节点 无法删除\n");//当遍历完整个链表,没有找到参数m
}
//头插法 来一个节点就插入到头的后面
void insert_head(struct node *head,struct node *newNode)
{
newNode->next = head->next;
newNode->prev = head;
head->next->prev = newNode;
head->next = newNode;
}
//尾插法 找到头节点即可,在头节点之前插入节点
void insert_last(struct node *head,struct node *newNode)
{
//不需要找最后一个节点 ,最后一个节点是head->prev保存的
newNode->next = head;//新节点的next指针指向头节点
newNode->prev = head->prev;//新节点的prev指针指向头节点的前一个节点
head->prev->next = newNode;//头节点的前一个节点的next指针指向新节点
head->prev = newNode;//头节点的prev指针指向新节点
}
//奇偶排序
void odd_even(struct node *head)
{
struct node *p = head->prev;//指向最后一个节点
struct node *tmp = p->prev;//指向p节点的前一个节点
while(p!=head)//遍历整个链表
{
tmp = p->prev;//每一次循环都遍历前一个节点
if (p->data%2 == 0)//如果该节点的数据是偶数,就执行以下语句
{
/*
思路:
1.判断该节点是否是偶数,若是偶数,进入第2步,否则跳过
1.删除该节点
2.将其插入到末尾
*/
p = delete_node(head,p->data);//删除该节点
insert_last(head,p);//再从尾部插入节点
}
p = tmp;//将P指针指向tmp指向的节点
if(p == head){//如果p指针指向了头节点
break;//直接跳出循环
}
}
}
int main(int argc, char const *argv[])
{
int i = 0;//循环变量
//初始化链表
struct node *head=init_list();
for (i = 1; i < 9; i++)
{
struct node *newNode = create_new_node(i);//创建节点
insert_node(head,newNode);//插入到链表当中
}
showlist(head);//打印链表
odd_even(head);//经过奇偶排序
printf("\n奇偶排序:\n");
showlist(head);//打印经过奇偶排序后的链表
return 0;
}
完
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix