鏈表
知識點摘於b站教程視頻: https://www.bilibili.com/video/av16869217?from=search&seid=12191125613016121321
b站教程視頻有些繁瑣。。。只看這篇文章鏈表入門應該可以理解接受
1.鏈表是存在於堆內存,存放在不連續的存儲空間,在這些不連續的存儲空間使用指針去作為一個索引。
a) 鏈表的結構體
struct Student{
int num;//學號 數據域
char name[10];//姓名 數據域
struct Student *pnext;//表示這個指針指向下一個節點(即下一個結構體) 指針域
};
p是指針 不斷用這個結構體的指針去指向下一個結構體,這就是一個鏈表。
b)節點是什么?
鏈表是由節點組成的,上圖中每個結構體就是鏈表的節點。
小tips:
typedef struct Student{
int num;//學號
char name[10];//姓名
struct Student *pnext;//表示這個指針指向下一個節點(即下一個結構體)
}STU;
//c語言中,如果加上了第一句的typedef ,STU就是一種數據類型(相當於struct Student、
)若沒有加typedef ,STU只是一個變量
//在c++中 ,Student可以直接作為數據類型。
2.兩種鏈表
3.動態內存的使用(鏈表)
STU *pStu=NULL; //相當於struct Student *pStu
pStu =(STU*)malloc(sizeof(STU)); //就是開辟一個節點
free(pStu);
4.創建鏈表頭結點:
STU* CreateList()
{
STU *P=(STU*)malloc(sizeof(STU));
P->pnext=NULL; //頭結點指向為空 (此時還不知道頭結點的下一個指向誰) 為保證安全性,賦值為空
return P;
//不需要給num和name賦值,因為是頭結點。
}
5.添加節點(按輸入順序添加節點)
添加一個節點
#include<stdio.h> #include<stdlib.h> typedef struct Student{ int num;//學號
char name[10];//姓名
struct Student *pnext;//表示這個指針指向下一個節點(即下一個結構體)
}STU; //創建鏈表的頭結點
STU* CreateList() { STU *P=(STU*)malloc(sizeof(STU)); P->pnext=NULL; return P; } //添加節點
void addNode(STU *P ) { STU *pNew=NULL;//重新定義一個指針
pNew=(STU*)malloc(sizeof(STU));//為新的指針開辟一塊內存
printf("請輸入學號:"); scanf("%d",&pNew->num); printf("請輸入姓名:"); scanf("%s",pNew->name); pNew->pnext=NULL;//為了安全,把指針指向定為空
P->pnext=pNew;//連接起來
} int main(){ STU* pStu = NULL;//定義一個指針,接受鏈表的首地址
pStu=CreateList();//頭結點
addNode(pStu);//添加一個節點 只添加了一個
printf("%d\t%s\n",pStu->pnext->num,pStu->pnext->name);//打印添加的節點
return 0; }
添加n個節點(人為控制添加的數量)
這個是初始狀態,形參指針P指向頭結點。
創建臨時變量pNew,賦值后,此時令pNew=P->pNext,完成結點之間的連接
再令P指向新的節點
再往下舉一個例子。
在for循環內創建一個新的pNew
給pNew賦值后,此時P指向第二個結點,令此時的pNew=P->pNext,完成結點之間的鏈接。
再令P指向新創建的節點。往后以此類推,形成鏈表。
實現代碼如下:
其中,addNode不一定非要輸入n個,可以自己添加限制條件,例如num==0時結束輸入
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct Student 5 { 6 int num;//學號 7 char name[10];//姓名 8 struct Student *pnext;//表示這個指針指向下一個節點(即下一個結構體) 9 } STU; 10 11 //創建鏈表的頭結點 12 STU* CreateList() 13 { 14 STU *P=(STU*)malloc(sizeof(STU)); 15 P->pnext=NULL; 16 return P; 17 } 18 19 //添加節點 人為控制添加的個數 20 void addNode(STU *P ) 21 { 22 STU * pNew=NULL; 23 int n;//當前要加入的節點的數量 24 scanf("%d",&n); 25 for(int i=0; i<n; i++) 26 { 27 pNew=(STU*)malloc(sizeof(STU)); 28 printf("請輸入學號:"); 29 scanf("%d",&pNew->num); 30 printf("請輸入姓名:"); 31 scanf("%s",pNew->name); 32 pNew->pnext=NULL;//尾節點設置為空 這個非常重要 33 34 P->pnext=pNew;//連接起來 35 P=P->pnext; 36 } 37 } 38 39 int main() 40 { 41 STU* pStu = NULL;//定義一個指針,接受鏈表的首地址 42 pStu=CreateList();//頭結點 43 44 addNode(pStu);//添加n個節點 45 46 printf("%d\t%s\n",pStu->pnext->num,pStu->pnext->name);//打印第二個節點的內容 47 48 49 return 0; 50 }
6.遍歷 打印出所有的信息
代碼如下:
1 void PrintAll(STU *P) 2 { 3 P=P->pnext;//P指向第一個有數據的節點
4 while(P!=NULL) 5 { 6 printf("%d\t%s\n",P->num,P->name); 7 P=P->pnext; 8 } 9 }
下面講,按輸入順序的逆序插入節點(即從中間插入節點)
這里頭結點用head代替比較明顯,前面頭結點用的是pStu,但是懶得重新再畫圖了。。。。
創建新節點pNew
第一步
再進行一步相同的操作。
由於head->pnext指向先創建的pNew,那么令第二次創建的pNew->pnext=head->pnext,而head->pnext又指向先創建的pNew,於是先創建的pNew和后創建的pNew就連接起來了。
然后令head->pnext=pNew,指向后創建的pNew。
那么這三個就形成了如下的鏈表:
練習題見隨筆---鏈表簡單練習題2