線性表是資料結構的重要組成部分。陣列和鍊錶是線性表的兩種常用表現形式,也是資料結構的基礎。
例如棧比較適用於陣列描述,佇列比較適用於鍊錶描述,樹葉比較適宜於鍊錶描述。資料結構的陣列描述和鍊錶描述的基本操作都涉及建立、元素插入和刪除操作等。本文主要介紹了線性表的鍊錶形式,並通過丟手帕例子介紹了鍊錶的建立、元素插入和元素刪除過程。
1
線性表
由零個或多個資料元素組成的有限序列,元素可以是c++的基本資料型別,也可以是自定義的抽象資料型別。該序列中所含元素的個數稱之為線性表的長度。線性表中元素在位置上是有序的。順序表和煉表是線性表的兩種重要形式。線性表中基本操作是鍊錶的建立、元素的插入和刪除、求線性表的長度和根據元素索引尋找相應元素等。
2
順序表
我們在學c基礎知識的時候就接觸了陣列,但當時並沒有涉及資料結構的概念,其實陣列就是一種簡單的線性表。雖然我們可以用乙個陣列儲存若干線性表的例項,但通常我們都是用乙個陣列儲存乙個線性表例項。
順序表的儲存形式是在記憶體中佔據了連續的記憶體空間。順序表有三個屬性:儲存空間的起始位置、順序表的最大儲存容量和順序表的當前長度。
3
鍊錶
每個元素用乙個單元或結點描述,每個結點有乙個用來指向下乙個元素的指標。鍊錶是在儲存
形式上非連續、邏輯形式上連續的資料結構,通過鍊錶中的指標
鏈結次序實現的。配合c++的new和delete操作可以進行動態地插入/刪除操作,增加/減小鍊錶的長度。為了**簡潔和高效,有時候我們增加乙個頭結點放在鍊錶最前面,它的資料域一般沒有具體意義,指標域指向第乙個節點。頭結點不是必須的。
最常用的就是單鏈表,如果把鍊錶的首尾鏈結起來,就是迴圈鍊錶;如果每乙個節點既有乙個指向後乙個元素的指標,又有指向前乙個元素的指標,我們稱它為雙向鍊錶。
下面用乙個例項,說明鍊錶的建立、插入和刪除等操作。引乙個約瑟夫問題,丟手帕問題也是從這個演變來的。在解決這個典型問題中,就用到了鍊錶的知識。據說著名猶太歷史學家 josephus有過以下的故事:在羅馬人占領喬塔帕特後,39 個猶太人與josephus及他的朋友躲到乙個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了乙個自殺方式,41個人排成乙個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下乙個重新報數,直到所有人都自殺身亡為止。然而josephus和他的朋友並不想遵從。首先從乙個人開始,越過k-2個人(因為第乙個人已經被越過),並殺掉第k個人。接著,再越過k-1個人,並殺掉第k個人。這個過程沿著圓圈一直進行,直到最終只剩下乙個人留下,這個人就可以繼續活著。問題是,給定了和,一開始要站在什麼地方才能避免被處決?josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。
先看看下面這個程式吧。
#includeusing namespace std;
class list //定義乙個類,這裡也可以定義為結構體;
int main()
p->next=head->next; //鍊錶首尾相連,此時的p仍然在建立的鍊錶的最後乙個節點
for(i=1;i<=number;i++)
coutlist*temp= new list; //new乙個臨時list型別指標,用於後面的刪除(出局)操作
while(number>0)
cout<
上面這個例子涉及到了鍊錶的建立、插入和刪除及元素索引操作,通過這個例子對鍊錶的操作進行綜合練習。此例的難點在於通過for迴圈或者用多個p->next(例如p->next->next;)找到需要出局的人,然後重新連線鍊錶並刪除出局的人。關於鍊錶的基礎操作,讀者可以在網上找些資料進行參考。
4
總結
順序表和煉表都是屬於線性表,它們有各自的優點和缺點進行總結。
順序表要求儲存空間是一段連續的記憶體,在順序表建立的時候要求確定線性表的容量,所以順序表的優缺點也顯而易見的。在尋找元素的時候可以根據下標快速找到,因此讀取元素的時間複雜度為o(1),順序表適用於索引元素操作;在插入/刪除元素時,因為元素是連續儲存的,所以要把插入/刪除元素之後的元素整體向後/向前移動,因此刪除和插入操作的時間複雜度為o(n),順序表不適用於頻繁地刪除和插入操作。因為是順序儲存,所以沒有類似鍊錶的指向下乙個元素的指標,儲存當前元素的下乙個記憶體空間就是下乙個元素。
優點:①可以快速訪問表中任意位置元素;
②無須為表中元素之間的邏輯關係而增加額外的儲存空間。
缺點:①插入和刪除操作移動大量元素;
②造成空間碎片。
鍊錶不要求儲存空間是一段連續的記憶體,也不要求在建立的時候確定線性表的容量,可以動態的增減長度,但必須有乙個用來指向下乙個元素的指標(單鏈表)。所以鍊錶在尋找元素的時候必須從頭結點開始逐個地向下進行,直到找到該元素或到尾結點。因此讀取元素的時間複雜度為o(n),鏈序表不適用於頻繁地索引元素操作;在插入/刪除元素時,因為元素根據指標相連的,所以只要移動相應結點的指標,就可以完成插入/刪除操作,而不影響其他元素,因此刪除和插入操作的時間複雜度為o(1),鍊錶適用於頻繁地刪除和插入操作。
優點:①不需要預先分配記憶體空間,儲存空間是動態增長的。
②可以快速地插入和刪除元素;
缺點:①索引元素較順序表速度慢;
②每個元素需要額外的乙個空間儲存指向下乙個元素的指標。
資料結構(線性表)
1.試寫一演算法,在無頭結點的動態單鏈表上實現線性表操作insert l,i,b 並和在帶頭結點的動態單鏈表上實現相同操作的演算法進行比較。status insert linklist l,int i,int b 在無頭結點鍊錶l的第 i個元素之前插入元素 belse insert 2.已知線性表中...
資料結構 線性表
參考 一 線性表 順序表 單鏈表 迴圈鍊錶 雙鏈表 順序表 1.表的初始化 void initlist seqlist l 2.求表長 int listlength seqlist l 3.取表中第i個結點 datatype getnode l,i 4.查詢值為x的結點 5.插入 具體演算法描述 v...
資料結構 線性表
線性表是最基礎的一種資料結構,這樣的資料物件包含的資料元素具有一對一的前驅後繼關係。按其邏輯儲存方式的不同可分為兩類線性表 順序表和鏈式表。其中鏈式表又可分為線性鍊錶 迴圈鍊錶和雙向鍊錶。下面分別介紹下這幾種線性表的資料結構 1.順序表 typedef struct sqlist 插入演算法 i到n...