链表 -- 双向链表

双向链表的创建

复制代码
 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 }
相关推荐
东风破_1 小时前
大前端手里的 Next.js:从 #root 到 SEO,一份 HTML 的两种命运
前端·后端
IT_陈寒1 小时前
Vue的v-for不听话?我被这个Key的坑整懵了
前端·人工智能·后端
2601_963869951 小时前
【计算机毕业设计】基于Java的相框定制系统的设计与实现
java·开发语言·课程设计
王林不想说话2 小时前
ES6 到 ES2026 全面进阶指南:新特性、原理、示例与工程落地
前端·javascript·面试
用户43523713814932 小时前
🚀 Vue3 + TypeScript 学习笔记:从泛型 T 到 Promise<T>,终于搞懂了 keyof 和 typeof
前端
跟着群主去吃肉2 小时前
Cinemachine的应用-第三人称视角
前端·unity3d·游戏开发
东方小月2 小时前
从零开发一个 Coding Agent(十):实现 CLI 参数解析与静态命令
前端·人工智能·开源
阿黎梨梨2 小时前
Next.js 全栈开发:从 SPA 的痛点到 SSR 的破局之道
前端·后端
沐道PHP2 小时前
CRMEB多店版diy装修位置偏移修复
前端