五、【线性表】线性表的链式表示和实现
線性表的鏈式表示和實現(xiàn)
上節(jié)提到,由于順序表的特點是邏輯關系上相鄰的兩個元素在物理位置上也相鄰,因此可以隨機存取表中任一元素。然而,這也導致了順序表在執(zhí)行插入或刪除操作時,需要移動大量元素。本節(jié)來討論線性表的另一種存儲方式——鏈式存儲結(jié)構(gòu)。
1 線性表的鏈式表示
1.1 單鏈表的定義 Single Linked List
線性表的鏈式存儲結(jié)構(gòu)的特點是用一組任意的存儲單元存儲線性表的數(shù)據(jù)元素,這些存儲單元可以連續(xù)也可以不連續(xù)。因此,為了表示每個數(shù)據(jù)元素與其后繼的邏輯關系,除了存儲其信息本身外,還需要存儲一個指示其后繼的信息(即其后繼的存儲地址)。這兩部分信息共同構(gòu)成一個數(shù)據(jù)元素的存儲映像,稱為結(jié)點(Node)。其中,存儲數(shù)據(jù)元素信息的域稱為數(shù)據(jù)域;存儲后繼存儲位置的域稱為指針域,指針域中存儲的信息稱為指針或鏈。
因為此類鏈表的每個結(jié)點中只包含一個指針域,故又稱為單鏈表或線性鏈表。
1.2 單鏈表的特點
換句話說,單鏈表中的數(shù)據(jù)元素之間的邏輯關系是由結(jié)點中的指針指示的,所以邏輯上相鄰的兩個元素不需要在物理地址上也相鄰,這種存儲結(jié)構(gòu)為非順序映像或鏈式映像。
在單鏈表中,只要知道前一個元素,通過指針就可以找到后一個元素。但是鏈表中的第一個數(shù)據(jù)元素就不是很好表達,因此我們需要引入“頭結(jié)點”(如下圖中的 head)。頭結(jié)點的作用是指向表中的第一個元素結(jié)點,頭結(jié)點的數(shù)據(jù)域中可以不存儲任何信息,也可以存儲表長等描述線性表的附加信息。若線性表為空表,則頭結(jié)點的指針域為空。
頭指針和頭結(jié)點
上圖中的單鏈表在第一個數(shù)據(jù)結(jié)點(即保存 a1a_1a1? 的結(jié)點)之前,還有一個和普通結(jié)點結(jié)構(gòu)一致的頭結(jié)點,包含數(shù)據(jù)域和指針域。還有一些鏈表沒有完整的頭結(jié)點,只有一個指針指向第一個數(shù)據(jù)結(jié)點,這個指針被稱為頭指針(可以看成是只包含指針域的頭結(jié)點)。
這兩種表示方法沒有區(qū)別,不管有沒有頭結(jié)點,頭指針都始終指向鏈表的第一個結(jié)點。但是為了操作方便,一般都加上頭結(jié)點。
總結(jié)
- 單鏈表不需要大量連續(xù)的存儲單元,可以更好地利用非連續(xù)內(nèi)存。
- 同時,由于單鏈表除了存儲數(shù)據(jù)元素本身,還存儲了指向下一個元素的指針,因此也需要浪費更多的存儲空間。
- 由于單鏈表的各元素離散地分布在存儲空間中,所以只能順序存取。如果要獲取第 nnn 個元素,必須先遍歷前 n?1n-1n?1 個元素,因此單鏈表的查找操作效率很低。
2 單鏈表的實現(xiàn)
2.1 結(jié)點的定義
要實現(xiàn)鏈表,首先要定義結(jié)點,按照定義,每一個結(jié)點包含存儲數(shù)據(jù)的數(shù)據(jù)域和存儲后繼位置的指針域:
/********** 單鏈表的定義 **********/ typedef int elemType; typedef struct LNode{elemType data; // 數(shù)據(jù)域struct LNode *next; // 指針域 } LNode, *LinkedList;其中我們給 LNode 定義了一個別名 LinkedList,這個類型別名是一個指針類型。實際上使用 LNode 和 LinkedList 會得到一樣的效果,但是使用合適的別名可以讓我們更好地理解代碼。當我們要使用的變量的功能側(cè)重于標識位置時,就聲明這個對象為 LinkedList ;當我們要使用的變量是結(jié)點時,就聲明這個對象為 LNode 。例如:
// 頭指針,尾指針和臨時指針 LinkedList head, tail, tmp; // 新結(jié)點n LNode *n;2.2 主要操作的實現(xiàn)
2.2.1 頭插法建立單鏈表
單鏈表的生成可以有兩種方式,從頭部插入和從尾部插入。其中頭插法從空表開始,每生成一個新結(jié)點,就插入當前鏈表的表頭,即頭結(jié)點之后。
/** Function: 頭插法建立單鏈表* ----------------------------* 從空表開始生成新結(jié)點,并將讀取到的數(shù)據(jù)存放到新結(jié)點的數(shù)據(jù)域中,* 然后將新結(jié)點插入到頭結(jié)點之后。*/ LinkedList headInsert(LinkedList &L){ LNode *n; // 先聲明一個結(jié)點指針n,用來指向?qū)砩傻男陆Y(jié)點elemType e; // 元素e,用來接收輸入的元素數(shù)據(jù)L = new LNode; // 創(chuàng)建頭結(jié)點L->next = NULL; // 初始為空鏈表scanf("%d", &e); while(e!=-1){n = new LNode; // 創(chuàng)建新結(jié)點n->data = e; n->next = L->next; // 將新結(jié)點插入頭結(jié)點之后L->next = n; scanf("%d", &e);}return L; // 返回頭結(jié)點 }時間復雜度分析
假設采用頭插法建立單鏈表,一共插入 nnn 個結(jié)點。對于單次插入操作來說,插入位置固定,因此操作時間復雜度和鏈表總長無關,時間復雜度為 O(1)O(1)O(1) 。總共插入 nnn 個結(jié)點,則總的時間復雜度為 O(n)O(n)O(n) 。
2.2.2 尾插法建立單鏈表
頭插法每一次都是在頭結(jié)點之后插入新結(jié)點,因此會導致元素的輸入順序和在鏈表中的存儲順序相反,有些不符合邏輯,尾插法可解決這一問題。尾插法是從空表開始,每一次將新結(jié)點插入到表尾。但是不同于頭結(jié)點,沒有一個特殊的指針指向表尾,所以我們需要建立一個尾指針并讓它始終指向表尾。
/** Function: 尾插法建立單鏈表* ----------------------------* 從空表開始生成新結(jié)點,并將讀取到的數(shù)據(jù)存放到新結(jié)點的數(shù)據(jù)域中,* 然后將新結(jié)點插入到鏈表的表尾。*/ LinkedList tailInsert(LinkedList &L){LNode *n; // 聲明新的結(jié)點nLinkedList t; // 聲明尾指針telemType e;L = new LNode; // 創(chuàng)建頭結(jié)點L->next = NULL;t = L; // 將指針t指向表尾,此時鏈表為空,表尾就是頭結(jié)點scanf("%d", &e);while (e!=-1){n = new LNode; // 創(chuàng)建新結(jié)點n->data = e;t->next = n; // 將新結(jié)點n加入鏈表t = n; // 將尾指針指向新結(jié)點nscanf("%d", &e);}t->next = NULL; // 將新的鏈表的尾結(jié)點指針置空return L; }時間復雜度分析
由于我們加入了尾指針,每一次插入操作只需要將新結(jié)點插入尾結(jié)點之后,單次插入操作的時間復雜度依然和鏈表總長度無關,時間復雜度為 O(1)O(1)O(1) 。假設總共插入 nnn 個結(jié)點,那么總的時間復雜度為 O(n)O(n)O(n) 。
2.2.3 按位查找結(jié)點操作
在單鏈表中查找第 iii 個結(jié)點,若找到則返回該結(jié)點,否則返回 NULL 。
/** Function: 按位查找結(jié)點* ----------------------------* 在單鏈表中從第一個結(jié)點出發(fā),直到找到第i個結(jié)點為止,* 否則返回最后一個結(jié)點指針域NULL。*/LNode *getElem(LinkedList L, int i){if (i<0){ // 檢查序號值是否合法return NULL;}LinkedList tmp=L; // 創(chuàng)建臨時指針,并指向頭結(jié)點for (int j=0;j<i;j++){ if (!tmp->next){ // 如果臨時指針的指針域為空, 則代表return NULL; // 臨時指針已位于表尾且仍未查到,返回NULL}tmp = tmp->next; }return tmp; // 如果for循環(huán)正常退出,// 則代表找到,返回臨時指針 }時間復雜度分析
基本操作為判斷結(jié)點是否為目標結(jié)點。
- 最優(yōu)情況:目標結(jié)點在表頭(即序號值 i=1i=1i=1),只需要判斷 1 次,因此時間復雜度為 O(1)O(1)O(1) 。
- 最差情況:目標結(jié)點在表尾(即序號值 i=ni = ni=n),共需要判斷 nnn 次,時間復雜度為 O(n)O(n)O(n) 。
- 平均情況:令 pip_ipi? 為目標元素在第 iii 個位置上的概率,假設目標元素出現(xiàn)在任意一個位置上的概率是相等的,那么 pi=1(n)p_i = \frac{1}{(n)}pi?=(n)1?。在長度為 nnn 的鏈表中查找一個元素時,所需移動元素的平均次數(shù)為
∑i=1npi?i=n+12\sum_{i=1}^{n} p_i*i = \frac{n+1}{2} i=1∑n?pi??i=2n+1?
所以平均時間復雜度為 O(n)O(n)O(n) 。
2.2.4 按值查找結(jié)點操作
在單鏈表中查找第一個數(shù)據(jù)域等于給定值 eee 的結(jié)點并返回,若未找到則返回 NULL 。
/** Function: 按值查找結(jié)點* ----------------------------* 在單鏈表中從第一個結(jié)點出發(fā),直到找到某個結(jié)點的數(shù)據(jù)域* 等于目標值為止,否則返回返回NULL。*/LNode *locateElem(LinkedList L, elemType e, int &count){LinkedList tmp=L->next; // 創(chuàng)建臨時指針,指向頭結(jié)點指針域count=1; // 記錄查找次數(shù)while (tmp!=NULL && tmp->data!=e){ // 如果臨時指針不為空且還未找到目標值,tmp = tmp->next; // 則繼續(xù)while循環(huán)count++;}return tmp; }時間復雜度分析
和按位查找一致。
2.2.5 插入結(jié)點操作
在指定位置 iii 插入新結(jié)點,如果 iii 的值不合法則返回 NULL 。
插入結(jié)點的操作可分為幾步:
因為第 1 步和第 2 步恰好是按位查找結(jié)點操作所做的事,所以可以借用按位查找來實現(xiàn)插入操作。
/** Function: 插入操作 * ----------------------------* 在指定位置i插入結(jié)點。* 借用getElem()方法可以將整個過程簡化為三步:* 1. tmp = getElem(L, i-1);* 2. n->next = tmp->next;* 3. tmp->next = n;*/LNode *listInsert(LinkedList &L, elemType e, int i){LinkedList tmp = getElem(L, i-1); // 首先使用按位查找檢測第i-1個結(jié)點是否存在,if (tmp==NULL){ // 即檢查插入位置的前驅(qū)結(jié)點是否存在return NULL;}LNode *n = new LNode; // 創(chuàng)建新結(jié)點n->data = e; n->next = tmp->next; // 將新結(jié)點插入第i-1個結(jié)點之后tmp->next = n;return tmp; }時間復雜度分析
根據(jù)前面分析,插入操作共分三步:
結(jié)合按位查找可簡化為:
因為按位查找操作的時間復雜度為 O(n)O(n)O(n) ,單次插入操作的復雜度為 O(1)O(1)O(1) ,所以總的時間復雜度為 O(max{O(n),O(1)})=O(n)O(max\{O(n), O(1)\}) = O(n)O(max{O(n),O(1)})=O(n) 。
2.2.5 刪除結(jié)點操作
刪除單鏈表的第 iii 個結(jié)點,如果 iii 的值不合法則返回 NULL 。分析同插入操作一致,重點是找到刪除結(jié)點的前驅(qū)結(jié)點。
/** Function: 刪除操作* ----------------------------* 刪除在指定位置i的結(jié)點。*/elemType listDelete(LinkedList &L, int i){LinkedList tmp = getElem(L, i-1); // 檢查刪除位置的前驅(qū)結(jié)點是否存在if (tmp==NULL || tmp->next==NULL){ // tmp不存在或者tmp就是最后一個結(jié)點,return -1; // 則不需要執(zhí)行刪除操作,直接返回}LinkedList q = tmp->next; // 指針q指向待刪除結(jié)點elemType e = q->data; // e用來保存刪除結(jié)點的值tmp->next = q->next; // 斷開q其他結(jié)點在鏈表中連接關系delete q; // 釋放結(jié)點的存儲空間return e; }時間復雜度分析
與插入操作一致。
3 其他常用操作
3.1 反轉(zhuǎn)鏈表操作
將鏈表所有元素的邏輯關系反轉(zhuǎn)(即前驅(qū)變?yōu)楹罄^)。
3.1.1 遍歷法實現(xiàn)反轉(zhuǎn)操作
基本思路是遍歷原鏈表,將每一個遍歷的元素指針反轉(zhuǎn)。但在過程中可能會出現(xiàn)鏈表斷裂的問題,如下圖所示:
當?shù)诙€結(jié)點指向改變時,鏈表在第二、三結(jié)點處斷裂,無法再獲取第三、四結(jié)點。因此,我們需要用一個變量來保存當前結(jié)點的后繼結(jié)點。一般需要三個指針,一個指向當前結(jié)點的前驅(qū)結(jié)點,定義為 pre ;一個指向當前結(jié)點,定義為 cur ;一個指向當前結(jié)點的后繼結(jié)點,定義為 next 。
時間復雜度分析
整個反轉(zhuǎn)過程可看成是遍歷 nnn 個元素以及依次反轉(zhuǎn)單個元素。反轉(zhuǎn)單個元素的時間復雜度為 O(1)O(1)O(1),遍歷的時間復雜度為 O(n)O(n)O(n) ,因此總的時間復雜度為 O(n)O(n)O(n) 。
3.1.2 遞歸法實現(xiàn)反轉(zhuǎn)操作
待補充。
3.2 合并有序鏈表操作
將有兩個有序鏈表合并為一個有序鏈表。
基本思路是分別用兩個指針遍歷兩個鏈表的元素,比較指針所指向結(jié)點的元素大小,將較小的先加入合并鏈表。
/** Function: 合并鏈表操作* ----------------------------* 將兩個鏈表的元素按大小關系*/LinkedList listMerge(LinkedList L1, LinkedList L2){LinkedList LM = new LNode; // 新的合并鏈表的頭結(jié)點LM->next = NULL;LinkedList tmp = LM;L1 = L1->next;L2 = L2->next;// 如果L1和L2都為空,那么直接返回空的LMif (L1==NULL && L2==NULL){return LM;}// 如果L1,L2其一不為空,或是都不為空,則直接開始比較while (true){// 當一方?jīng)]有剩余結(jié)點時,退出循環(huán)if (L1==NULL || L2==NULL){break;}// 比較兩個鏈表中的元素大小,較小的先加入合并鏈表if (L1->data <= L2->data){tmp->next = L1;tmp = tmp->next;L1 = L1->next;} else {tmp->next = L2;tmp = tmp->next;L2 = L2->next;}}// 當一方已經(jīng)完成遍歷時,將另一方的剩余結(jié)點全部加入合并鏈表if (L1==NULL){tmp->next = L2;} else {tmp->next = L1;}return LM; }上述實現(xiàn)方法會破壞原鏈表,在確定不會再使用原鏈表后才可使用。例如:
// L1 = 1 3; // L2 = 2 4;LinkedList LM = listMerge(L1, L2); listPrint(L1); listPrint(L2); listPrint(LM);輸出: L1: 1 2 3 4 L2: 2 3 4 LM: 1 2 3 4時間復雜度分析
合并有序鏈表的基本操作是兩個鏈表內(nèi)元素的比較,假設鏈表的長度分別為 LaLaLa 和 LbLbLb ,那么總的比較次數(shù)最多為 La+Lb?1La +Lb -1La+Lb?1 。例如:a={1,3,5},b={2,4,6}a = \{1, 3, 5\}, b = \{2, 4, 6\}a={1,3,5},b={2,4,6} ,總的比較次數(shù)為 5 。
因此最差時間復雜度為 O(La+Lb)O(La + Lb)O(La+Lb) 。
相關章節(jié)
第一節(jié) 【緒論】數(shù)據(jù)結(jié)構(gòu)的基本概念
第二節(jié) 【緒論】算法和算法評價
第三節(jié) 【線性表】線性表概述
第四節(jié) 【線性表】線性表的順序表示和實現(xiàn)
第五節(jié) 【線性表】線性表的鏈式表示和實現(xiàn)
第六節(jié) 【線性表】雙向鏈表、循環(huán)鏈表和靜態(tài)鏈表
第七節(jié) 【棧和隊列】棧
第八節(jié) 【棧和隊列】棧的應用
第九節(jié) 【棧和隊列】棧和遞歸
第十節(jié) 【棧和隊列】隊列
附錄
單鏈表實現(xiàn)的完整代碼
/** File name: LinkedList.h* -----------------------* Using struct to implement LinkedList*/#ifndef _SINGLE_LINKED_LIST_h_ #define _SINGLE_LINKED_LIST_h_ #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std;/********** 單鏈表的定義 **********/ typedef int elemType; typedef struct LNode{elemType data; // 數(shù)據(jù)域struct LNode *next; // 指針域 } LNode, *LinkedList;/********** 基本操作的實現(xiàn) **********/ /** Function: 頭插法建立單鏈表* ----------------------------* 從空表開始生成新結(jié)點,并將讀取到的數(shù)據(jù)存放到新結(jié)點的數(shù)據(jù)域中,* 然后將新結(jié)點插入到頭結(jié)點之后。*/ LinkedList headInsert(LinkedList &L){ // L是一個指針LNode *n; // 先聲明一個結(jié)點指針n,用來指向?qū)砩傻男陆Y(jié)點elemType e; // 元素e,用來接收輸入的元素數(shù)據(jù)L = new LNode; // 創(chuàng)建頭結(jié)點L->next = NULL; // 初始為空鏈表scanf("%d", &e); while(e!=-1){n = new LNode; // 創(chuàng)建新結(jié)點n->data = e; n->next = L->next; // 將新結(jié)點插入頭結(jié)點之后L->next = n;scanf("%d", &e);}return L; // 返回頭結(jié)點 }/** Function: 尾插法建立單鏈表* ----------------------------* 從空表開始生成新結(jié)點,并將讀取到的數(shù)據(jù)存放到新結(jié)點的數(shù)據(jù)域中,* 然后將新結(jié)點插入到鏈表的表尾。*/ LinkedList tailInsert(LinkedList &L){LNode *n; // 聲明新的結(jié)點nLinkedList t; // 聲明尾指針telemType e;L = new LNode; // 創(chuàng)建頭結(jié)點L->next = NULL;t = L; // 將指針t指向表尾,此時鏈表為空,表尾就是頭結(jié)點scanf("%d", &e);while (e!=-1){n = new LNode; // 創(chuàng)建新結(jié)點n->data = e;t->next = n; // 將新結(jié)點n加入鏈表t = n; // 將尾結(jié)點指向新結(jié)點nscanf("%d", &e);}t->next = NULL; // 將新的鏈表的尾結(jié)點指針置空return L; }/** Function: 判空操作* ----------------------------* 判斷鏈表是否為空。*/bool listEmpty(LinkedList L){return !L->next; // 如果只有頭結(jié)點,則鏈表為空 }/** Function: 求表長操作* ----------------------------* 計算單鏈表中結(jié)點的個數(shù),不包括頭結(jié)點。*/int listLength(LinkedList L){int count=0; // 用來計算結(jié)點個數(shù)LinkedList tmp=L;while (tmp->next!=NULL){tmp = tmp->next;count++;}return count; }/** Function: 按位查找結(jié)點* ----------------------------* 在單鏈表中從第一個結(jié)點出發(fā),直到找到第i個結(jié)點為止,* 否則返回最后一個結(jié)點指針域NULL。*/LNode *getElem(LinkedList L, int i){if (i<0){ // 檢查序號值是否合法return NULL;}LinkedList tmp=L; // 創(chuàng)建臨時指針,并指向頭結(jié)點for (int j=0;j<i;j++){ if (!tmp->next){ // 如果臨時指針的指針域為空, 則代表return NULL; // 臨時指針已位于表尾且仍未查到,返回NULL}tmp = tmp->next; }return tmp; // 如果for循環(huán)正常退出,// 則代表找到,返回臨時指針 } /** Function: 按值查找結(jié)點* ----------------------------* 在單鏈表中從第一個結(jié)點出發(fā),直到找到某個結(jié)點的數(shù)據(jù)域* 等于目標值為止,否則返回返回NULL。*/LNode *locateElem(LinkedList L, elemType e, int &count){LinkedList tmp=L->next; // 創(chuàng)建臨時指針,指向頭結(jié)點指針域count=1; // 記錄查找次數(shù)while (tmp!=NULL && tmp->data!=e){ // 如果臨時指針不為空且還未找到目標值,tmp = tmp->next; // 則繼續(xù)while循環(huán)count++;}return tmp; }/** Function: 插入操作 * ----------------------------* 在指定位置i插入結(jié)點。* 借用getElem()方法可以將整個過程簡化為三步:* 1. tmp = getElem(L, i-1);* 2. n->next = tmp->next;* 3. tmp->next = n;*/LNode *listInsert(LinkedList &L, elemType e, int i){LinkedList tmp = getElem(L, i-1); // 首先使用按位查找檢測第i-1個結(jié)點是否存在,if (tmp==NULL){ // 即檢查插入位置的前驅(qū)結(jié)點是否存在return NULL;}LNode *n = new LNode; // 創(chuàng)建新結(jié)點n->data = e; n->next = tmp->next; // 將新結(jié)點插入第i-1個結(jié)點之后tmp->next = n;return tmp; }/** Function: 刪除操作* ----------------------------* 刪除在指定位置i的結(jié)點。*/elemType listDelete(LinkedList &L, int i){LinkedList tmp = getElem(L, i-1); // 檢查刪除位置的前驅(qū)結(jié)點是否存在if (tmp==NULL || tmp->next==NULL){ // tmp不存在或者tmp就是最后一個結(jié)點,return -1; // 則不需要執(zhí)行刪除操作,直接返回}LinkedList q = tmp->next; // 指針q指向待刪除結(jié)點elemType e = q->data; // e用來保存刪除結(jié)點的值tmp->next = q->next; // 斷開q其他結(jié)點在鏈表中連接關系delete q; // 釋放結(jié)點的存儲空間return e; }/** Function: 輸出操作* ----------------------------* 按順序從頭到尾輸出單鏈表的元素*/void listPrint(LinkedList L){LinkedList tmp=L;while (tmp->next!=NULL){tmp = tmp->next;printf("%d ", tmp->data);}printf("\n"); }#endif // _SINGLE_LINKED_LIST_h單鏈表檢測程序
/** File name: LinkedList.cpp* -----------------------* Using struct to implement LinkedList*/#include "LinkedList.h"int main() {LinkedList L; // 頭結(jié)點int n, i, res;elemType e;LinkedList node;char helpInfo[] ="*****************************\n""Linked list check: \n""\t1-Create linked list by head insertion\n""\t2-Create linked list by tail insertion\n""\t3-Insert element\n""\t4-Delete element\n""\t5-Print\n""\t6-Empty check\n""\t7-Get Length\n""\t8-Search by value\n""\t9-Search by location\n""\t10-Quit\n""*****************************\n";while (n != 10) {printf(helpInfo);scanf("%d", &n);switch (n) {case 1:printf("Head insertion:\n");printf("Enter -1 to quit.\n");headInsert(L);break;case 2:printf("Tail insertion:\n");printf("Enter -1 to quit.\n");tailInsert(L);break;case 3:printf("Please enter the location: \n");scanf("%d", &i);printf("Please enter the element: \n");scanf("%d", &e);listInsert(L, e, i);break;case 4:printf("Please enter the location: \n");scanf("%d", &i);res = listDelete(L, i);if (res == -1) {printf("Didn't find the target node.\n");} else {printf("Target node in location %d with value %d is ""deleted.\n",i, res);}break;case 5:printf("List: ");listPrint(L);break;case 6:if (listEmpty(L)) {printf("This list is empty.\n");} else {printf("This list is not empty.\n");}break;case 7:printf("Length of list is: %d\n", listLength(L));break;case 8:printf("Please enter the target value: ");scanf("%d", &e);node = locateElem(L, e, i);if (!node) {printf("Didn't find the target node.\n");} else {printf("The index of target is: %d\n", i);}break;case 9:printf("Please enter the target index: ");scanf("%d", &i);node = getElem(L, i);if (!node) {printf("Didn't find the target node.\n");} else {printf("The value of target is %d\n", node->data);}break;}}return 0; }總結(jié)
以上是生活随笔為你收集整理的五、【线性表】线性表的链式表示和实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四、【线性表】线性表的顺序表示和实现
- 下一篇: 七、【栈和队列】栈