C++編程語言實現單鏈表詳情
一、單鏈表簡單介紹
首先,我們再回顧一下線性表的兩種存儲方式——順序存儲與鏈式存儲
上圖左邊為順序存儲,右邊為鏈式存儲
之前我們利用數組來實現順序表,對於順序表的優點缺點,總結來說就是,查找方便,增刪復雜。
線性表之順序存儲的優缺點
而鏈表特點可以說恰恰相反,增刪方便,查找復雜。
今天實現的是鏈表中最簡單的一種——單鏈表(每個結點中隻含有一個指針域)
對於鏈表我們隻知道它每個結點的存儲的物理地址是不連續的,但邏輯上還是符合線性表“一對一”的特點。因此,我們就需要用“線”(指針)把這些不連續的結點按順序連接起來。
鏈表的結點在內存中存儲不連續
通過指針把每個結點按順序連起來
到這裡我們可以發現,要想表示鏈表中的結點,光存儲結點的數據是不夠的,還得有指針。因此,單鏈表的結點結構如下:
數據域存儲數據,指針域存儲指針
//================線性表的單鏈表存儲結構================= typedef struct LNode { ElemType data;//數據域 struct LNode *next;//指針域 }LNode;
註意:因為指針是指向每個結點的,也就是指向struct LNode
這個自定義的結構體類型,所以指針的類型就是struct LNode*。
二、下面我們先實現單鏈表的初始化。
單鏈表的初始化其實就是創建幾個結點,然後用指針把他們連接起來。
先創建一個頭指針,實際上就是創建一個頭結點,然後頭指針指向頭結點就OK
LNode* CreateList_L(int n) {//順位序輸入n個元素的值,建立帶表頭結點的單鏈線性表L LNode *p = (LNode*)malloc(sizeof(LNode));//創建頭結點(p也就是頭指針) LNode *temp = p;//聲明一個指針指向頭結點,用於遍歷鏈表(不是頭指針,因為它隻是暫時指向頭結點) //生成鏈表 for (int i = n; i > 0; --i) { LNode *node = (LNode *)malloc(sizeof(LNode));//創建結點 if (node){//分配地址成功 scanf_s("%c", &(node->data)); node->next = NULL; //建立新結點與直接前驅結點的邏輯關系 temp->next = node; temp = temp->next; } else {//如果分配地址失敗,則返回錯誤信息 printf("結點創建失敗!\n"); } } return p; }
三、實現單鏈表的插入與刪除數據
單鏈表插數據情況
觀察可知,我們要實現插入操作,需要的操作是一樣的。
S1:將後繼結點的指針賦給新結點的指針域;
S2:將前驅節點的指針域改為指向新結點的指針。
註意:S1和S2不能換順序。
//===============================算法2.9========================== Status ListInsert_L(LNode *L, int i, ElemType e) { //在帶頭結點的單鏈表L中第i個位置之前插入元素e int j = 0; LNode *p = L; while (p&&j < i - 1) { p = p->next; ++j; }//尋找第i-1個結點 if (!p || j > i - 1)return ERROR;//i小於1或者大於表長時 LNode* s = (LNode*)malloc(sizeof(LNode));//生成新的結點 s->data = e; s->next = p->next;//S1 p->next = s;//S2 return OK; }
單鏈表刪除數據示意圖
觀察可知,隻需要將待刪結點的前驅結點的指針域的值換成待刪結點的後繼結點的指針即可。
//=====================算法2.10================================= Status ListDelete_L(LNode *L, int i, ElemType *e) { //在帶頭結點的單鏈表L中,刪除第i個元素,並由e返回其值 LNode *p = L; int j = 0; while (p->next&&j < i - 1) {//尋找第i個結點,並令p指向其前驅 p = p->next; ++j; } if (!(p->next) || j > i - 1)return ERROR;//刪除位置不合理 LNode *q = p->next; p->next = q->next;//刪除並釋放結點 *e = q->data; free(q); return OK; } 三、參考代碼實現與截圖 #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define ElemType char typedef int Status; //================線性表的單鏈表存儲結構================== typedef struct LNode { ElemType data;//數據域 struct LNode *next;//指針域 }LNode; LNode* CreateList_L(int n) {//順位序輸入n個元素的值,建立帶表頭結點的單鏈線性表L LNode *p = (LNode*)malloc(sizeof(LNode));//創建頭結點 LNode *temp = p;//聲明一個指針指向頭結點,用於遍歷鏈表(不是頭指針) //生成鏈表 for (int i = n; i > 0; --i) { LNode *node = (LNode *)malloc(sizeof(LNode));//創建結點 if (node){//分配地址成功 scanf_s("%c", &(node->data)); node->next = NULL; //建立新結點與直接前驅結點的邏輯關系 temp->next = node; temp = temp->next; } else {//如果分配地址失敗,則返回錯誤信息 printf("結點創建失敗!\n"); } } return p; } //===============================算法2.9========================== Status ListInsert_L(LNode *L, int i, ElemType e) { //在帶頭結點的單鏈表L中第i個位置之前插入元素e int j = 0; LNode *p = L; while (p&&j < i - 1) { p = p->next; ++j; }//尋找第i-1個結點 if (!p || j > i - 1)return ERROR;//i小於1或者大於表長時 LNode* s = (LNode*)malloc(sizeof(LNode));//生成新的結點 s->data = e; s->next = p->next; p->next = s; return OK; } //=====================算法2.10================================= Status ListDelete_L(LNode *L, int i, ElemType *e) { //在帶頭結點的單鏈表L中,刪除第i個元素,並由e返回其值 LNode *p = L; int j = 0; while (p->next&&j < i - 1) {//尋找第i個結點,並令p指向其前驅 p = p->next; ++j; } if (!(p->next) || j > i - 1)return ERROR;//刪除位置不合理 LNode *q = p->next; p->next = q->next;//刪除並釋放結點 *e = q->data; free(q); return OK; } void display(LNode *L) { LNode *temp =L;//將temp指針重新指向頭結點 //隻要temp指針指向的結點的next不是Null,就執行輸出語句。 while (temp->next) { temp = temp->next; printf("%c", temp->data); } printf("\n"); } int main() { LNode *L = NULL; L=CreateList_L(5); display(L); ListInsert_L(L, 2, 'Y'); display(L); ElemType e; ListDelete_L(L, 2, &e); display(L); printf("返回值為:%c", e); system("pause"); return 0; }
初始化鏈表為abcdef
,在第2個位置插入Y,然後刪除Y
到此這篇關於C++編程語言實現單鏈表詳情的文章就介紹到這瞭,更多相關C++編程語言實現單鏈表內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!