链表 -- 双向链表

双向链表的创建

复制代码
 3 node_t* dlinklist_creat(void)
  4 {
  5     node_t*head=malloc(sizeof(node_t));
  6     if(head==NULL)
  7     {
  8         printf("malloc fail\n");
  9         return NULL;
 10     }
 11     head->next=NULL;
 12     head->prev=NULL;
 13     return head;
 14 }

与单向链表的区别在于结构体多了一个指向前节点的指针

双向链表的头插入

复制代码
 16 void dlinklist_insert_head(node_t *phead,data_t d)
 17 {
 18     if(phead==NULL)
 19         return;                                                                                                                                                                  
 20     node_t *new_p=malloc(sizeof(node_t));
 21     if(new_p==NULL)
 22     {   
 23         printf("malloc fail\n");
 24         return;
 25     }
 26     new_p->data=d;
 27     new_p->next=phead->next;
 28     new_p->prev=phead;
 29     phead->next=new_p;
 30     if(new_p->next!=NULL)
 31         new_p->next->prev=new_p;
 32 }

判断链表是否为空

复制代码
 34 int is_empty(node_t*phead)
 35 {   
 36     if(phead->next==NULL)
 37         return 1;
 38     return 0;
 39 }

打印链表

复制代码
 41 void dlinklist_print(node_t*phead,int dir)
 42 {   
 43     if(phead==NULL || is_empty(phead))
 44         return;
 45     node_t*p=phead->next;
 46     if(dir==1)
 47     {
 48         while(p!=NULL)
 49         {
 50             printf("%d ",p->data);
 51             p=p->next;
 52         }
 53     }else if(dir == 0)
 54     {
 55         while(p->next!=NULL)
 56         {
 57             p=p->next;      //p到达尾节点
 58         }
 59         while(p->prev!=NULL)
 60         {
 61             printf("%d ",p->data);
 62             p=p->prev;
 63         }
 64     }                                                                                                                                                                            
 65     putchar('\n');
 66     return;
 67 }

链表长度计算

复制代码
 69 int length(node_t *phead)                                                                                                                                                        
 70 {
 71     if(phead==NULL || is_empty(phead))
 72         return 0;
 73     node_t *p=phead->next;
 74     int cnt=0;
 75     while(p!=NULL)
 76     {
 77         cnt++;
 78         p=p->next;
 79     }
 80     return cnt;
 81 }

双向链表尾插入

复制代码
 83 void dlinklist_insert_tail(node_t *phead,data_t d)
 84 {                                                                                                                                                                                
 85     if(phead==NULL)
 86         return;
 87     node_t *p_new=malloc(sizeof(node_t));
 88     if(p_new==NULL)
 89     {
 90         printf("malloc fail\n");
 91         return;
 92     }
 93     node_t *p_end=phead;
 94     while(p_end->next!=NULL)
 95     {
 96         p_end=p_end->next;
 97     }
 98     p_new->data=d;
 99     p_new->next=NULL;
100     p_new->prev=p_end;
101     p_end->next=p_new;
102 }

双向链表查找

复制代码
104 node_t* dlinklist_find_key(node_t*phead,data_t key)
105 {
106     if(phead==NULL || is_empty(phead))
107         return NULL;
108     node_t*p=phead->next;
109     while(p!=NULL && p->data!=key)
110     {
111         p=p->next;
112     }
113     return p;
114 }

双向链表修改

复制代码
116 void dlinklist_updata_key(node_t*phead,data_t old_val,data_t new_val)
117 {
118     if(phead==NULL || is_empty(phead))
119         return;
120     node_t*p=dlinklist_find_key(phead,old_val);
121     if(p==NULL)
122         return;
123     p->data=new_val;
124 }

双向链表删除(头删、尾删、指定删)

复制代码
126 int dlinklist_del_head(node_t*phead)     //返回值1代表成功删除,0代表列表无法删除
127 {
128     if(phead==NULL || is_empty(phead))
129         return 0;
130     node_t*p=phead->next;
131     phead->next=p->next;
132     if(p->next!=NULL)
133     {
134         p->next->prev=phead;
135     }
136     free(p);
137     p=NULL;
138     return 1;
139 }
140 
141 int dlinklist_del_tail(node_t*phead)     //返回值1代表成功删除,0代表列表无法删除
142 {
143     if(phead==NULL || is_empty(phead))
144         return 0;
145     node_t*p=phead->next;
146     while(p->next!=NULL)
147     {
148         p=p->next;
149     }
150     p->prev->next=NULL;
151     free(p);
152     return 1;
153 }
154 int dlinklist_del_key(node_t*phead,data_t key)
155 {
156     if(phead==NULL || is_empty(phead))
157         return 0;
158     node_t*p=dlinklist_find_key(phead,key);
159     if(p==NULL)
160         return 0;
161     p->prev->next=p->next;
162     if(p->next!=NULL)
163         p->next->prev=p->prev;
164     free(p);
165     return 1;
166 }

销毁双向链表

复制代码
168 int dlinklist_destroy(node_t**phead)
169 {
170     if(*phead==NULL)
171         return 0;
172     if(is_empty(*phead)==1)
173     {
174         free(*phead);
175         *phead=NULL;
176         return 1;
177     }
178     node_t *p=(*phead)->next;
179     while(p)
180     {
181         node_t *p_temp=p;
182         p=p->next;
183         free(p_temp);
184     }
185     free(*phead);
186     *phead=NULL;
187     return 1;
188 }
相关推荐
鲨鱼辣钊21 分钟前
【FastAPI筑基-Day19】APScheduler定时任务全实战|自动执行、动态启停、后台常驻
java·spring·fastapi
ℋᙚᵐⁱᒻᵉ鲸落4 小时前
移动端滑动手势冲突:overflow: auto导致外层横向滑动失效
前端·javascript·css·vue.js·html
学长毕业设计5 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
东小西5 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西5 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring
许彰午5 小时前
22-DataCenter报文序列化
java·低代码·架构·状态模式
2601_962065255 小时前
[MySQL] SQL优化之性能分析
java·sql·mysql
默_笙6 小时前
🎃 前端学了 Next.js,后端该学啥?NestJS 就是 Node 版的蜜雪冰城
前端·javascript
小范同学_6 小时前
JDK1.7 与 JDK1.8 HashMap 底层原理对比 + 数组并发扩容死循环详解
java·开发语言
予昊7 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket