標籤:結構 單向鏈表 附加 node 基本操作 logs style tno 通過
用C語言的指標實現了單向鏈表中的幾項基本操作:建立鏈表,置空鏈表,插入節點(由於在尾部加入新節點尤為常用,故單獨用一個函數實現),刪除節點。為了以上操作更便捷,另分別寫了返回尾節點和某特定節點的函數。
為了統一插入及刪除節點的操作,使其不因節點位置不同而受到影響(主要是插入或刪除前端節點),我在真正的表頭(我稱之為true_head)前加入一空節點作為表頭。
另外,在特定位置插入、刪除節點時必須確保此位置是有效。想法是:在表頭中儲存鏈表的長度,在特定位置插入、刪除時,將此位置與長度比較大小,如果位置大於長度,則報錯;如果位置小於長度,則執行操作並更新表頭中的長度資訊。長度資訊的更新:建立時置為1,置空時重設為0,插入成功則加1,刪除成功則減1。
用結構體定義:
1 typedef struct Node{2 int i;3 struct Node *next;4 }Node;
建立鏈表:這是唯一一個需要返回頭指標的函數。
1 Node *MakeList(void)//建立帶有空表前端節點的列表並返回表頭,其中表頭儲存的是鏈表的長度 2 { 3 Node *head = (Node *)malloc(sizeof(Node)); 4 Node *true_head = (Node *)malloc(sizeof(Node)); 5 printf("Please type in the element of the head node:"); 6 scanf("%d", &true_head->i); 7 head->next = true_head; 8 true_head->next = NULL; 9 head->i = 1;10 return head;11 }
置空鏈表:
1 void MakeNull(Node *head)2 {3 head->next = NULL;4 head->i = 0;5 }
插入節點:
1 void Insert(Node *head, int i)//在特定位置插入節點 2 { 3 if(i > (head->i + 1))//注意:在i或者i+1位置都沒有問題,在i+1位置相當於Append 4 { 5 printf("Insertion failed because i is too big!\n"); 6 } 7 else 8 { 9 Node *temp = (Node *)malloc(sizeof(Node));10 printf("Please type in the element of the new node:");11 scanf("%d", &temp->i);12 Node *pre = GetNode(head, i-1);13 Node *aft = pre->next;//剛開始以為要把在表尾的插入單獨拿出來討論,但後來發現此時aft不就是NULL了嘛?(′▽` )14 temp->next = aft;15 pre->next = temp;16 head->i++;17 }
1 void Append(Node *head)//在鏈表尾部附加節點 2 { 3 Node *temp = (Node *)malloc(sizeof(Node)); 4 printf("Please type in the element of the new node:"); 5 scanf("%d", &temp->i); 6 Node *pre = GetTail(head); 7 pre->next = temp; 8 temp->next = NULL; 9 head->i++;10 }
刪除節點:
1 void Remove(Node *head, int i)//刪除特定節點 2 { 3 if(i > head->i) 4 { 5 printf("Removal failed because i is too big!\n"); 6 } 7 else 8 { 9 Node *pre = GetNode(head, i-1);//同插入,尾節點也不需要拿出來10 Node *temp = pre->next;11 pre->next = temp->next;12 head->i--;13 }14 }
其他的:
1 Node *GetNode(Node *head, int i)//傳入節點位置,並返回此節點 2 { 3 if(i > head->i) 4 { 5 printf("Failed to get node i because i is too big!\n"); 6 return NULL; 7 } 8 else 9 {10 Node *temp = head;11 int k;12 for(k = 0; k < i; k++)13 {14 temp = temp->next;15 }16 return temp;17 }18 }19 20 Node *GetTail(Node *head)//返回鏈表尾節點,便於在鏈表尾插入新節點21 {22 Node *temp = head;23 while(NULL != temp->next)24 {25 temp = temp->next;26 }27 return temp;28 }29 30 void PrintList(Node *head)//按從表頭到表尾的順序列印鏈表31 {32 Node *temp = head->next;//從真表頭開始列印33 if(NULL == temp)34 {35 printf("There is no element in the list!\n");36 }37 else38 {39 int k;40 for(k = 0; k < head->i; k++)41 {42 printf("%d\n", temp->i);43 temp = temp->next;44 }45 }46 }
問題們:
由於指標掌握不好,對於一些操作有些不知所以然;增加一個指標指向尾節點,就可以把GetTail替換掉,但是在進行插入刪除操作時可能會增加額外的工作;希望增加通過元素返回節點位置的操作。
單向鏈表的C語言實現