鏈表:創建一個簡單的鏈表並輸出鏈表內容


鏈表的專業術語:

  首節點:存放第一個有效數據的節點
  尾節點:存放最后一個有效數據的節點
  頭結點
      1.頭結點的數據類型和首節點的數據類型是一模一樣的
      2.頭結點是首節點前面的那個節點
      3.頭結點並不存放有效數據
      4.設置頭結點的目的是為了方便對鏈表的操作
  頭指針:存放頭結點地址的指針變量

用一張圖片來展示鏈表的基本框架:

⭐尾節點的指針域為空,可以表示為NULL

⭐想要確定一個鏈表,需要最基本的信息是頭指針,之后的信息都可以通過頭指針找出來。

接下來編寫程序,只有用實際的例子,才能更全面的理解!

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 struct Node                          //定義一個鏈表結構 
 4 {
 5     int data;                        //鏈表節點的數據 
 6     struct Node * pNext;             //鏈表節點指向下一個節點的指針 
 7 };
 8 int i;
 9 struct Node * create_list(void);     //創建鏈表的函數聲明 
10 void traverse_list(struct Node *);   //打印鏈表的函數聲明 
11 int main()
12 {
13     struct Node * pHead = NULL;     //先給頭指針賦值為NULL 
14     pHead = create_list();          //調用鏈表創建函數,並將頭指針的值賦給pHead 
15     traverse_list(pHead);           //打印鏈表
16     return 0;
17 }
18 struct Node * create_list(void)     //創建鏈表的函數
19 {
20     int len;                        //鏈表的節點數 
21     int val;                        //鏈表節點中數據域的值 
22     struct Node * pHead=(struct Node *)malloc(sizeof(struct Node));  //動態分配頭結點的內存 
23     if(pHead == NULL)
24     {
25         printf("內存分配失敗,程序終止!\n");
26         exit(-1);
27     }
28     struct Node * pTail = pHead;                        //定義一個尾節點指針,將pHead的值賦給它 
29     pTail->pNext = NULL;                                //尾節點的指針域一定為空 
30     printf("請輸入您需要生成的鏈表節點的個數:len =");
31     scanf("%d",&len);
32     for (i=0;i<len;i++)
33     {
34         printf("請輸入第%d個節點的值:",i+1);
35         scanf("%d",&val);
36         struct Node * pNew=(struct Node *)malloc(sizeof(struct Node));  //動態分配新節點的內存
37         if(pNew== NULL)
38     {
39         printf("內存分配失敗,程序終止!\n");
40         exit(-1);
41     }
42         pNew->data = val;       //把輸入的值傳給*pNew數據域 
43         pNew->pNext = NULL;     // *pNew是新的尾節點,所以 pNew->pNext應該為空
44         pTail->pNext = pNew;    //把*pNew的地址傳給pTail->pNext指針域,等效於*pTail.pNext=pNew
45                                 //第一次的pTail->pNext = pNew相當於把首節點的地址給了頭結點
46                                 
47         pTail = pNew;           48                                 //執行此操作,*pNew就變成了新的*pTail 
49                                 //之后的pTail = pNew則是讓最后一個與上一個節點連接上     
50      } 
51     return pHead;               //返回 pHead的值 
52 }
53 void traverse_list(struct Node * pHead)  //遍歷鏈表 
54 {
55     struct Node * p = pHead->pNext;      //定義一個指向下一個節點的指針 
56     while(p!=NULL)                       //尾節點的指針域一定是NULL,如果非NULL,則繼續打印 
57     {
58         printf("%d\t",p->data);
59         p = p->pNext;                    //下一個節點的地址賦值給p 
60     }
61     return;                              //循環結束 
62 }

在這個程序中,我對44行和47行的代碼思考了很久

最開始總覺得有了44行代碼 pTail->pNext = pNew ,47行的代碼 pTail = pNew 重復了,刪去之后,發現不行,下面對兩者的區別進行畫圖解析:

 

 

第1步:*pTail的地址就是pHead,所以pHead指向*pTail,另外,新創建的*pNew還沒有賦值。

第2步:將val賦值給*pNew的數據域,NULL賦值給*pNew的指針域,並把*pNew的地址傳給*pTail的指針域

第3步:把*pNew的地址賦值給pTail,讓*pNew變成新的*pTail

整個過程大致就是如此,理解了,其實也不難,要掌握更多的知識,需要進一步學習數據結構。


免責聲明!

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



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