单链表基本操作(尾插 尾删 头插头删等)

LinkList.h



  1 #ifndef __LINKLIST__
  2 #define __LINKLIST__
  3 //#pragma once
  4 #include <stdlib.h>
  5 typedef char LinkNodeType;
  6 
  7 typedef struct LinkNode{
  8     LinkNodeType data;
  9     struct LinkNode* next;
 10 }LinkNode;
 11 typedef struct LinkList{
 12     LinkNode* head;
 13     LinkNode* tail;
 14 }LinkList;
 15 
 16 LinkNode* CreateNode(LinkNodeType value);
 17 
 18 
 19 typedef LinkNode* PLinkNode;
 20 
 21 void LinkListInit(PLinkNode*);//初始化
 22 
 23 void LinkListDestroy(PLinkNode*);//销毁
 24 
 25 void LinkListPushBack(LinkNode** head,LinkNodeType value);//尾插
 26 
 27 void LinkListPopBack(LinkNode** phead);//尾删
 28 
 29 void LinkListPushFront(LinkNode** phead,LinkNodeType value);//头插
 30 
 31 void LinkListPopFront(LinkNode** phead);//头删
 32 
 33 void LinkListInsert(LinkNode* pos,LinkNodeType value);//将新节点插入pos之后
 34 
 35 void LinkListInsertBefore(LinkNode** head,LinkNode* pos,LinkNodeType value);//将新节点插入pos之后
 36 

 37 void LinkListInsertBefore2(LinkNode* pos,LinkNodeType value);//将新节点插入pos之后

 38 
 39 void LinkListErase(LinkNode** pead,LinkNode* pos);//删除指定下标(遍历)
 40 
 41 void LinkListErase2(LinkNode** pead,LinkNode* pos);//删除指定下标(非遍历)
 42 
 43 void LinkListRemove(LinkNode** phead,LinkNodeType to_remove);//删除指定元素
 44 
 45 void LinkListRemoveAll(LinkNode** phead,LinkNodeType to_remove);//删除所有指定元素
 46 
 47 int LinkListEmpty(LinkNode* head);//判断是否空链表
 48 
 49 size_t LinkListSize(LinkNode* head);//链表长度
 50 
 51 LinkNode* LinkListFind(LinkNode* head,LinkNodeType to_find);

 52 #endif





LinkList.c





  1 #include "LinkList.h"
  2 #include <stdlib.h>
  3 #include <stdio.h>
  4 LinkNode* CreateNode(LinkNodeType value){
  5     LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));
  6     new_node->data = value;
  7     new_node->next = NULL;
  8     return new_node;
  9 }
 10 
 11 void DestroyNode(LinkNode* node){
 12     free(node);
 13 }
 14 
 15 void LinkListInit(PLinkNode* node){
 16     *node = NULL;
 17 }
 18 
 19 void LinkListPrintChar(LinkNode* head,const char* msg){
 20     printf("[%s]\n",msg);
 21     LinkNode* cur = head;
 22     for(;cur != NULL; cur = cur->next){
 23         printf("[%c|%p] ",cur->data,cur);
 24     }
 25     printf("\n");
 26 }
 27 
 28 void LinkListDestroy(PLinkNode* phead){
 29     //TODO
 30     (void) phead;
 31 }
 32 
 33 void LinkListPushBack(LinkNode** phead,LinkNodeType value){
 34     if (phead == NULL){
 35         //error input
 36         return;

 37     }

 38 if (*phead ==NULL){
 39     //空
 40     *phead = CreateNode(value);
 41     return;
 42 }
 43 //非空
 44 LinkNode* cur = *phead;
 45 while(cur->next != NULL){
 46     cur = cur->next;
 47 }
 48 LinkNode* new_node = CreateNode(value);
 49 cur->next = new_node;
 50 return;
 51 }
 52 
 53 void LinkListPopBack(LinkNode** phead){
 54     if (phead == NULL){
 55         //非法输入
 56         return;
 57     }
 58     if (*phead == NULL){
 59         //空链表无法删除
 60         return;
 61     }
 62     if ((*phead)->next == NULL){
 63         //只有一个元素
 64         DestroyNode(*phead);
 65         *phead = NULL;
 66         return;
 67         }
 68     LinkNode* pre = NULL;
 69     LinkNode* cur = *phead;
 70     while(cur->next != NULL){
 71         pre = cur;
 72         cur = cur->next;
 73     }

 74     pre->next = NULL;

 75     DestroyNode(cur);
 76 }
 77 
 78 void LinkListPushFront(LinkNode** phead,LinkNodeType value){
 79     if (phead == NULL){
 80         //非法输入
 81         return;
 82     }
 83     LinkNode* new_node = CreateNode(value);
 84     new_node->next = *phead;
 85     *phead = new_node;
 86 }
 87 
 88 
 89 void LinkListPopFront(LinkNode** phead){
 90     if(phead == NULL){
 91         //非法输入
 92         return;
 93     }
 94     if (*phead == NULL){
 95         //空链表
 96         return;
 97     }
 98     LinkNode* to_earse = *phead;
 99     *phead=(*phead)->next;
100     DestroyNode(to_earse);
101     return;
102 }
103 
104 
105 void LinkListInsert(LinkNode* pos,LinkNodeType value){//将新节点插入pos之后
106 
107     if( pos == NULL){
108         //非法输入,pos 表示存在一个节点的指针,如果pos为空,说明根本不存在这样的节点
109         return;
110     }

111     LinkNode* new_node = CreateNode(value);

112     new_node->next = pos->next;
113     pos->next = new_node;
114     return;
115 }
116 
117 
118 void LinkListInsertBefore(LinkNode** phead,LinkNode* pos,LinkNodeType value){//将新节点插入pos之前
119     if ( phead ==NULL || pos == NULL){
120         //非法输入
121         return;
122     }
123     if (*phead == pos){
124         //要插入的位置刚好是头结点
125         LinkListPushFront(phead,value);
126         return;
127     }
128     LinkNode* cur = *phead;
129     for (;cur != NULL;cur = cur->next){
130         if (cur->next == pos){
131             break;
132         }
133     }
134     //循环结束后需知道那种情况结束,是否找到pos
135     if (cur == NULL){
136         return;
137     }
138     LinkListInsert(cur,value);
139 
140 }
141 
142 
143 void LinkListInsertBefore2(LinkNode* pos,LinkNodeType value){//将新节点插入pos之后
144     if ( pos == NULL){
145         //非法输入
146         return;
147     }

148     LinkNode* new_node = CreateNode(pos->data);

149     new_node->next = pos->next;
150     pos->next = new_node;
151     pos->data = value;
152 }
153 
154 
155 void LinkListErase(LinkNode** phead,LinkNode* pos){
156     if (phead == NULL || pos == NULL){
157         //非法输入
158         return;
159     }
160     if (*phead == NULL){
161         //空链表
162         return;
163     }
164     LinkNode* cur = *phead;
165     for (;cur != NULL;cur = cur->next){
166         if (cur->next == pos){
167             break;
168         }
169 
170     }
171     //循环结束要判定是否找到
172     if (cur == NULL){
173         return;
174     }
175     cur->next = pos->next;
176     DestroyNode(pos);
177     return;
178 }
179 
180 
181 void LinkListErase2(LinkNode** phead,LinkNode* pos){
182     if (phead == NULL || pos == NULL){
183         //非法输入
184         return;

185     }

186     if (*phead == NULL){
187         //空链表
188         return;
189     }
190     if (pos->next == NULL){
191         //要删除的元素刚好是最后一个元素,只能使用尾删方式了,只能遍历链表
192         LinkListPopBack(phead);
193         return;
194     }
195     pos->data = pos->next->data;
196     LinkNode* to_erase = pos->next;
197     pos->next = to_erase->next;
198     DestroyNode(to_erase);
199     return;
200 
201 
202 }
203 
204 
205 LinkNode* LinkListFind(LinkNode* head,LinkNodeType to_find){
206     if (head ==NULL){
207         //空链表
208         return NULL;
209     }
210     LinkNode* cur = head;
211     while(cur){
212         if(cur->data == to_find){
213             return cur;
214         }
215         cur = cur->next;
216     }
217     return NULL;
218 }
219 
220 
221 void LinkListRemove(LinkNode** phead,LinkNodeType to_remove){

222     if ( phead ==NULL){

223         //非法输入
224         return;
225     }
226     if ( *phead == NULL){
227         //空链表
228         return;
229     }
230     if ( (*phead)->data == to_remove){
231         //删除第一个元素
232         LinkNode* to_delete = *phead;
233         *phead = (*phead)->next;
234         DestroyNode(to_delete);
235         return;
236     }
237     LinkNode* cur = *phead;
238     for(;cur->next != NULL;cur = cur->next){
239         if (cur->next->data == to_remove){
240             //cur所在下一值为删除元素,cur是要删除元素的前一位置
241             LinkNode* to_delete = cur->next;
242             cur->next = to_delete->next;
243             DestroyNode(to_delete);
244         }
245     }
246 }
247 
248 
249 void LinkListRemoveAll(LinkNode** phead,LinkNodeType to_remove){
250     if ( phead ==NULL){
251         //非法输入
252         return;
253     }
254     if ( *phead == NULL){
255         //空链表
256         return;
257     }
258     LinkNode* cur = *phead;

259     for(;cur->next !=NULL;cur = cur->next){

260         while(cur->next->data == to_remove){
261             LinkNode* to_delete = cur->next;
262             cur->next = to_delete->next;
263             DestroyNode(to_delete);
264         }
265     }
266 }
267 
268 
269 int LinkListEmpty(LinkNode* head){
270     return head == NULL?1:0;
271 }
272 
273 
274 size_t LinkListSize(LinkNode* head)
275 {
276     if(head == NULL)
277     {
278         //空链表
279         return 0;
280     }
281     LinkNode* pos = head;
282     size_t count = 0;
283     while(pos != NULL){
284         ++count;
285         pos = pos->next;
286     }
287     return count;

288 }





test.c




  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "LinkList.h"
  4 
  5 
  6 void TestInit(){
  7     LinkNode* head;
  8     LinkListInit(&head);
  9 }
 10 
 11 
 12 void TestPushBack(){
 13     LinkNode* head;
 14     LinkListInit(&head);
 15     LinkListPushBack(&head,'a');
 16     LinkListPushBack(&head,'b');
 17     LinkListPushBack(&head,'c');
 18     LinkListPushBack(&head,'d');
 19     LinkListPrintChar(head,"尾插四个元素");
 20 }
 21 
 22 void TestPopBack(){
 23     LinkNode* head;
 24     LinkListInit(&head);
 25     LinkListPopBack(&head);
 26     LinkListPrintChar(head,"对空链表删除");
 27     LinkListPushBack(&head,'a');
 28     LinkListPopBack(&head);
 29     LinkListPrintChar(head,"对一个元素链表删除");
 30     LinkListPushBack(&head,'a');
 31     LinkListPushBack(&head,'b');
 32     LinkListPushBack(&head,'c');
 33     LinkListPushBack(&head,'d');
 34     LinkListPopBack(&head);
 35     LinkListPrintChar(head,"尾删一个元素");
 36     LinkListPopBack(&head);

 37     LinkListPopBack(&head);

 38     LinkListPrintChar(head,"尾删两个元素");
 39 }
 40 
 41 void TestPushFront(){
 42     LinkNode* head;
 43     LinkListInit(&head);
 44     LinkListPushFront(&head,'a');
 45     LinkListPushFront(&head,'b');
 46     LinkListPushFront(&head,'c');
 47     LinkListPushFront(&head,'d');
 48     LinkListPrintChar(head,"头插四个元素");
 49 }
 50 
 51 void TestPopFront(){
 52     LinkNode* head;
 53     LinkListInit(&head);
 54     LinkListPopFront(&head);
 55     LinkListPrintChar(head,"尝试对空链表头删");
 56     LinkListPushFront(&head,'a');
 57     LinkListPushFront(&head,'b');
 58     LinkListPushFront(&head,'c');
 59     LinkListPrintChar(head,"插入三个元素");
 60     LinkListPopFront(&head);
 61     LinkListPopFront(&head);
 62     LinkListPrintChar(head,"头删两个元素");
 63 }
 64 void TestInsert(){
 65     LinkNode* head;
 66     LinkListInit(&head);
 67     LinkListPushFront(&head,'a');
 68     LinkListPushFront(&head,'b');
 69     LinkListPushFront(&head,'c');
 70     LinkNode* pos = head->next;
 71     LinkListInsert(pos,'x');
 72     LinkListPrintChar(head,"在b之后插入x");
 73 }

 74 

 75 void TestInsertBefore(){
 76     LinkNode* head;
 77     LinkListInit(&head);
 78     LinkListPushFront(&head,'a');
 79     LinkListPushFront(&head,'b');
 80     LinkListPushFront(&head,'c');
 81 
 82     LinkNode* pos1 = head;
 83     LinkListInsertBefore(&head,pos1,'x');
 84     LinkListPrintChar(head,"在头结点之前插入节点");
 85 
 86     LinkNode* pos2 = head->next->next;
 87     LinkListInsertBefore(&head,pos2,'y');
 88     LinkListPrintChar(head,"在b之前插入节点");
 89 
 90 }
 91 
 92 void TestInsertBefore2(){
 93     LinkNode* head;
 94     LinkListInit(&head);
 95     LinkListPushFront(&head,'a');
 96     LinkListPushFront(&head,'b');
 97     LinkListPushFront(&head,'c');
 98 
 99     LinkNode* pos1 = head;
100     LinkListInsertBefore2(pos1,'x');
101     LinkListPrintChar(head,"在头结点之前插入节点");
102 
103 
104     LinkNode* pos2 = head->next->next;
105     LinkListInsertBefore2(pos2,'y');
106     LinkListPrintChar(head,"在b之前插入节点");
107 
108 }
109 
110 void TestErase(){

111     LinkNode* head;

112     LinkListInit(&head);
113     LinkListErase(&head,(LinkNode*)0x11);
114     LinkListPrintChar(head,"尝试对空链表删除");
115 
116     LinkListPushBack(&head,'a');
117     LinkListPushBack(&head,'b');
118     LinkListPushBack(&head,'c');
119     LinkListPushBack(&head,'d');
120     LinkNode* pos = head->next;
121     LinkListErase(&head,pos);
122     LinkListPrintChar(head,"删除元素b");
123 
124     LinkNode* pos2 = (LinkNode*)0x10;
125     LinkListErase(&head,pos);
126     LinkListPrintChar(head,"尝试对一个不存在的位置删除");
127 }
128 
129 void TestErase2(){
130     LinkNode* head;
131     LinkListInit(&head);
132     LinkListErase(&head,(LinkNode*)0x11);
133     LinkListPrintChar(head,"尝试对空链表删除");
134 
135     LinkListPushBack(&head,'a');
136     LinkListPushBack(&head,'b');
137     LinkListPushBack(&head,'c');
138     LinkListPushBack(&head,'d');
139     LinkNode* pos = head->next;
140     LinkListErase2(&head,pos);
141     LinkListPrintChar(head,"删除元素b");
142 
143     LinkNode* pos2 = (LinkNode*)0x10;
144     LinkListErase2(&head,pos);
145     LinkListPrintChar(head,"尝试对一个不存在的位置删除");
146 }
147 

148 void TestFind(){

149     LinkNode* head;
150     LinkListInit(&head);
151     LinkListPushBack(&head,'a');
152     LinkListPushBack(&head,'b');
153     LinkListPushBack(&head,'c');
154     LinkListPushBack(&head,'d');
155     LinkNode* pos_x = LinkListFind(head,'x');
156     printf("pos_x expected NULL,actual %p\n",pos_x);
157     LinkNode* pos_b = LinkListFind(head,'b');
158     printf("pos_b expected NULL,actual %p\n",head->next,pos_b);
159 }
160 
161 void TestRemove(){
162     LinkNode* head;
163     LinkListInit(&head);
164     LinkListPushBack(&head,'a');
165     LinkListPushBack(&head,'b');
166     LinkListPushBack(&head,'b');
167     LinkListPushBack(&head,'c');
168     LinkListPushBack(&head,'d');
169     LinkListRemove(&head,'b');
170     LinkListPrintChar(head,"删除元素b");
171 }
172 
173 void TestRemoveAll(){
174     LinkNode* head;
175     LinkListInit(&head);
176     LinkListPushBack(&head,'a');
177     LinkListPushBack(&head,'b');
178     LinkListPushBack(&head,'b');
179     LinkListPushBack(&head,'c');
180     LinkListPushBack(&head,'d');
181     LinkListRemoveAll(&head,'b');
182     LinkListPrintChar(head,"删除所有元素b");
183 }
184 

185 int TestEmpty(){

186     LinkNode* head;
187     LinkListInit(&head);
188     LinkListPushBack(&head,'a');
189     LinkListEmpty(head);
190 }
191 
192 void TestLinkListSize(){
193     LinkNode* head;
194     LinkListInit(&head);
195     LinkListPushBack(&head,'a');
196     LinkListPushBack(&head,'b');
197     LinkListPushBack(&head,'b');
198     LinkListPushBack(&head,'c');
199     LinkListPushBack(&head,'d');
200     size_t ret = LinkListSize(head);
201     printf("size = %d\n",ret);
202 }
203 
204 int main(){
205     TestInit();
206     TestPushBack();
207     TestPopBack();
208     TestPushFront();
209     TestPopFront();
210     TestInsert();
211     TestInsertBefore();
212     TestInsertBefore2();
213     TestErase();
214     TestErase2();
215     TestFind();
216     TestRemove();
217     TestRemoveAll();
218     TestEmpty();
219     TestLinkListSize();
220     return 0;
221 }

阅读更多
换一批

没有更多推荐了,返回首页