線性表的鏈式儲存結構生成的表,稱作「鍊錶」。
鍊錶分為單向鍊錶和雙向鍊錶。
單鏈表(singly linked list)是用一組任意的儲存單元存放的線性表元素,這組儲存單元可以連續也可以不連續,甚至可以零散分布在記憶體中的任意位置。為了能夠體現出資料元素之間的邏輯關係,每個儲存單元在在儲存資料元素的同時,還必須儲存其後繼元素所在的位址資訊,這個位址資訊稱為指標,這兩部分組成了資料元素的儲存映像,稱為結點(node)。
鍊錶的簡單原理圖如圖:
結點結構如圖所示:
每個元素本身由兩部分組成:
data 稱為「資料域」,用來存放資料元素(可以是乙個成員,或多個成員);
next 稱為「指標域」,用來存放該結點的後繼結點的位址。
單鏈表正是通過每個結點的指標域將線性表的資料元素按其邏輯次序鏈結在一起,由於每個結點只有乙個指標域,故稱為單鏈表。
單鏈表中每個結點的儲存位址存放在其前驅結點的next域中,而第乙個元素無前驅,所以設頭指標(head pointer)指向第乙個元素所在結點(稱為開始結點),整個單鏈表的訪問必須從頭指標開始進行,因而頭指標具有標識乙個單鏈表的作用;同時,由於最後乙個元素無後繼,故最後乙個元素所在結點(稱為終端結點)的指標域為空,即null。
指向第乙個結點(開始結點)的指標必須儲存,否則該鍊錶將會消失。通常在單鏈表的開始結點之前附設乙個型別相同的結點,稱為頭結點(head node)。加上頭結點之後,無論單鏈表是否為空,頭指標始終指向頭結點。
typedef int elementtype;
struct node
;
在構建鍊錶時,需要逐個建立結點,並且把生成的每個結點加入到鍊錶中。建立結點包括3個步驟:
為結點分配記憶體單元;
把資料儲存到結點中;
把結點插入到鍊錶中。
鍊錶的建立
建立乙個僅含頭結點的空鍊錶:
typedef struct node *list;
int icount = 0; //記錄鍊錶長度的全域性變數
list initlist()
鍊錶還可以使用頭指標建立
list initlist()
遍歷操作
遍歷列印鍊錶元素
void printlist(list l)
}
求線性表長度
int length(list l)
return count;
}
查詢操作
按位查詢:從頭結點出發順next域逐個結點向下搜尋,當工作指標p指向某個結點時判斷是否為第 i 個結點,若是,則查詢成功;否則,將工作指標後移。對每個結點依次執行上述操作,知道p為null時查詢失敗。
elementtype getdata(list l, int i)
if(p == null)
else
return p->data;
}
按值查詢:對鍊錶中的元素依次進行比較,如果查詢成功,返回元素的序號,如果查詢不成功,則返回0表示查詢失敗。
int locate(list l, elementtype element)
return 0; //表示查詢失敗,返回0
}
插入操作
每次加入乙個結點,使用迴圈可建立乙個含有n個結點的單鏈表
頭插法:
頭插法是每次將新申請的結點插在頭結點的後面,其執行過程如圖所示。
}尾插法:
尾插法就是每次將新申請的結點插在終端結點的後面,其執行過程如圖所示。
}和前面的建立初始化寫在一起可以建立乙個含n個元素的鍊錶。
向鍊錶中任意位置插入結點,插入到第 i 個位置,即插入到鍊錶 i-1 與 i 之間。必須先掃瞄鍊錶找到 i-1 的儲存位址 p ,然後生成乙個新的結點 pnew,將 pnew 的next域指向第 i 個結點,將結點 p 的next域指向新結點。
void insert(list l, int i, elementtype element)
if(p == null)
else
}
刪除操作
將單鏈表的第 i 個結點刪去,首先要找到 i-1 個結點的儲存位址p,然後令p的next域指向 i 的後繼結點,釋放結點 i 的儲存空間。被刪結點的的前驅結點p存在且不是終端結點時,才能確定被刪結點存在。
void delete(list l, int i)
if(p == null || p->next == null)
else
}
刪除整個鍊錶
void deletelist(list l)
}
線性表 鍊錶(二)
一,單鏈表的插入 1 單鏈表如何插入乙個新元素呢?在單鏈表中 有序對 圖例 注意 在單鏈表中插入只需要修改指標。若要在第 i 個結點之前插入元素,修改的是是第 i 1 個結點的指標。2 單鏈表的插入元素的 怎麼寫呢?如下 status listinsert linklist l,int i elem...
線性表 鍊錶(二)
單迴圈鍊錶 由上一節的單向鍊錶可知,如果我們想要遍歷鍊錶中的所有元素必須要知道鍊錶的頭結點,通過頭結點開始順著指標鏈依次訪問每個結點,知道最後乙個結點,因此訪問的方式受到了一定的限制,假設我們知道的是鍊錶中的任意乙個結點,那麼,要想訪問單鏈表的所有結點我們該怎麼辦呢?所以我們要引入一種新的鍊錶形式來...
線性表 鍊錶
線性表的adt list.h 線性表的c 抽象類宣告 templateclass list 單鏈表節點的定義 link.h 單鏈表節點類的定義 template class link link link nextval null 鍊錶的實現宣告 成員函式的是實現 鍊錶的實現宣告 include st...