單向鏈表的C語言實現


用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     else
38     {
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替換掉,但是在進行插入刪除操作時可能會增加額外的工作;希望增加通過元素返回節點位置的操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM