在說鏈表之前,我們先說說順序存儲。其中我們最熟悉的一種順序存儲的數據結構就是數組,當我們想要給數組中插入一個元素時,為保證順序以及其他元素不丟失,我們需要在插入元素后,將后面的元素整體后移。所以容易看出這樣有着這兩個弊端:第一:我們所需要移動的元素有很多時,會浪費算力。第二:我們必須為數組開足夠多的空間,否則會存在溢出風險。
為了避免這兩個弊端,我們引入鏈式存儲——鏈表。
什么是鏈表?
簡單來說,鏈表的利用結構體,額外開辟出一份內存空間去作指針,它總是指向下一個結點,一個個結點通過指針相互串聯,這就形成了我們的鏈表。
其中DATA數據元素(數據域),可以是int類型或char類型,甚至可以是結構體。NEXT為一個指針通常是用來指向下一個結點,鏈表的尾部NEXT指向NULL,因為它沒有可以指向的空間了。
對於一個單鏈表的結點定義:
``
1 //定義結點類型 2 typedef struct Node 3 { 4 int DATA;//數據域 5 struct Node* NEXT;//指針域 6 }Node,* pointnode;//Node表示結點的類型,pointnode表示指向Node結點類型的指針類型 7 ``` 8 1.對鏈表進行初始化: 9 10 ```c 11 pointnode Initialize() 12 { 13 Node* H=(Node*)malloc(sizeof(Node)); //開辟空間 14 if(H==NULL) //判斷是否開辟成功 15 { 16 printf("開辟失敗!");//開辟失敗的提示 17 exit(0); // 開辟失敗結束程序(根據情況看是否添加) 18 } 19 H->NEXT=NULL; //指針指向NULL 20 } 21 ``` 22 2.創建單鏈表: 23 <1>頭插法 24 從一個空表開始,生成新結點,並將數據存放到新結點的數據域中,然后將新結點插入到當前鏈表的表頭即頭結點之后。 25 ```c 26 pointnode listofhead() 27 { 28 Node* H = (Node*)malloc(sizeof(Node));//開辟一個頭空間 29 H -> NEXT= NULL; //初始化為空 30 31 int x; 32 while (scanf("%d", &x) != EOF) //輸入數據,當輸入空的時候停止(在Windows下:Ctrl+Z) 33 { 34 Node* p = (Node*)malloc(sizeof(Node)); 35 p->DATA = x; //賦值給數據域 36 p->NEXT = H->NEXT; //將節點插到表頭 37 H->NEXT = p; 38 } 39 return H; 40 } 41 ``` 42 <2>尾插法 43 將新結點逐個插入到當前鏈表的表尾上,增加一個尾指針, 使其始終指向當前鏈表的尾結點。 44 ```c 45 pointnode listofend() 46 { 47 Node* H = (Node*)malloc(sizeof(Node)); //開辟頭空間 48 H->NEXT = NULL; //初始化 49 50 int x; 51 Node* l; //定義為尾指針 52 l = H; // 尾指針開始指向頭,始終指向尾。 53 while (scanf("%d", &x) != EOF) 54 { 55 Node* p = (Node*)malloc(sizeof(Node)); 56 p->DATA = x; 57 l->NEXT = p; //將結點插到表頭 58 l = p; 59 60 } 61 l->NEXT = NULL; 62 return H; 63 } 64 ``` 65 注意:頭插法的順序是逆序的:表頭->[n]->···->[2]->[1]->NULL 66 尾插法是正序的:表頭->[1]->[2]->····[n]->NULL 67 3.鏈表的遍歷 68 69 ```c 70 void listoftravel(pointnode H) 71 { 72 Node* p = H->NEXT; 73 74 int i = 1; 75 while (p) 76 { 77 printf("第%d個數據是%d\n", i++, p->DATA); 78 p = p->NEXT; 79 } 80 81 }
2.鏈表的插入
1 //鏈表的插入 2 pointnode datainlist(pointnode H,int i,int x) 3 { 4 Node* preve = H; 5 int seek; 6 for (seek = 1; seek < i; seek++)//尋找元素位置 7 { 8 preve = preve->NEXT; 9 } 10 Node* p = (Node*)malloc(sizeof(Node)); 11 p->DATA = x; 12 p->NEXT = preve->NEXT; 13 preve->NEXT = p; 14 return H; 15 }
3.鏈表修改
//鏈表的修改 pointnode moddata(pointnode H,int x,int t) { Node* p = H->NEXT; while (p) { if (p->DATA == x) { p->DATA = t; } p = p->NEXT; } return H; }
4.鏈表刪除
//鏈表的刪除 pointnode freedata(pointnode H,int x) { Node* p; Node* preve;//前驅結點 p = H->NEXT; while (p->DATA != x)//查找元素 { preve = p; p = p ->NEXT; } preve->NEXT = p->NEXT; free(p); //刪除操作 return H; }
5.完整代碼

#include<stdio.h> #include<stdlib.h> //定義結點類型 typedef struct Node { int DATA;//數據域 struct Node* NEXT;//指針域 }Node, * pointnode; //Node表示結點的類型,pointnode表示指向Node結點類型的指針類型 //鏈表的初始化 pointnode Initialize() { Node* H = (Node*)malloc(sizeof(Node)); //開辟空間 if (H == NULL) //判斷是否開辟成功 { printf("開辟失敗!");//開辟失敗的提示 exit(0); // 開辟失敗結束程序(根據情況看是否添加) } H->NEXT = NULL; //指針指向NULL } //頭插法建立鏈表 pointnode listofhead() { Node* H = (Node*)malloc(sizeof(Node));//開辟一個頭空間 H = NULL; //初始化為空 int x; while (scanf("%d", &x) != EOF) //輸入數據,當輸入空的時候停止(在Windows下:Ctrl+Z) { Node* p = (Node*)malloc(sizeof(Node)); p->DATA = x; //賦值給數據域 p->NEXT = H->NEXT; //將節點插到表頭 H->NEXT = p; } return H; } //尾插法 pointnode listofend() { Node* H = (Node*)malloc(sizeof(Node)); //開辟頭空間 H->NEXT = NULL; //初始化 int x; Node* l; //定義為尾指針 l = H; // 尾指針開始指向頭,始終指向尾。 while (scanf("%d", &x) != EOF) { Node* p = (Node*)malloc(sizeof(Node)); p->DATA = x; l->NEXT = p; //將結點插到表頭 l = p; } l->NEXT = NULL; return H; } //遍歷鏈表 void listoftravel(pointnode H) { Node* p = H->NEXT; int i = 1; while (p) { printf("第%d個數據是%d\n", i++, p->DATA); p = p->NEXT; } } //鏈表的插入 pointnode datainlist(pointnode H,int i,int x) { Node* preve = H; int seek; for (seek = 1; seek < i; seek++)//尋找元素位置 { preve = preve->NEXT; } Node* p = (Node*)malloc(sizeof(Node)); p->DATA = x; p->NEXT = preve->NEXT; preve->NEXT = p; return H; } //鏈表的修改 pointnode moddata(pointnode H,int x,int t) { Node* p = H->NEXT; while (p) { if (p->DATA == x) { p->DATA = t; } p = p->NEXT; } return H; } //鏈表的刪除 pointnode freedata(pointnode H,int x) { Node* p; Node* preve;//前驅結點 p = H->NEXT; while (p->DATA != x)//查找元素 { preve = p; p = p ->NEXT; } preve->NEXT = p->NEXT; free(p); //刪除操作 return H; } int main() { pointnode list; Initialize(); list = listofend(); //list = listofhead(); listoftravel(list); //鏈表的修改 int x; int t; printf("你想修改的數據是:"); scanf("%d", &x); printf("你想把他改為:"); scanf("%d", &t); moddata(list, x, t); listoftravel(list); //鏈表的插入 int i; printf("你想在哪個位置插入數據:"); scanf("%d", &i); printf("你想插入的數據是:"); scanf("%d", &x); datainlist(list, i, x); listoftravel(list); //鏈表的刪除 printf("你想刪除的數據是:"); scanf("%d", &x); freedata(list, x); listoftravel(list); return 0; }
希望大家也可以關注本人的CSDN,內容都是一致的!如有錯誤,請指正!!