第四章
This presentation is the property of its rightful owner.
Sponsored Links
1 / 33

第四章 — 鏈結串列 PowerPoint PPT Presentation


  • 81 Views
  • Uploaded on
  • Presentation posted in: General

第四章 — 鏈結串列. 4.1 單一鏈結串列與鏈 鏈結串列畫出時如一連串節點,其中箭頭表示指標鏈結 ( 圖 4.1) 。指向串列第一個節點的指標之名稱也是串列的名稱。亦即,圖 4.1 中的串列稱為 prt 。 ptr 圖 4.1 :畫出鏈結串列常用的方法 要在 cat 和 sat 之間插入 mat ,我們必須: 取得一個目前未使用的節點;令其位址為 paddr 。 將此節點的資料欄位設定為 mat 。. 3. 將 paddr 的鏈結欄位設定為包含 cat 的節點之鏈結欄位中找到的位址。

Download Presentation

第四章 — 鏈結串列

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


6522348

第四章—鏈結串列


6522348

  • 4.1 單一鏈結串列與鏈

  • 鏈結串列畫出時如一連串節點,其中箭頭表示指標鏈結(圖4.1)。指向串列第一個節點的指標之名稱也是串列的名稱。亦即,圖4.1中的串列稱為prt。

    ptr

    圖4.1:畫出鏈結串列常用的方法

  • 要在cat和sat之間插入mat,我們必須:

    • 取得一個目前未使用的節點;令其位址為paddr。

    • 將此節點的資料欄位設定為mat。


6522348

3. 將paddr的鏈結欄位設定為包含cat的節點之鏈結欄位中找到的位址。

4. 設定包含cat的節點之鏈結欄位,使其指向paddr。

  • 圖4.2表示在插入mat以後串列的改變。從包含cat的結點出來的虛線為舊的鏈結,實線為新的鏈結。

    ptr

    圖4.2:在cat之後插入mat

  • 假設我們想要自串列中刪除mat。只要找到在mat之前的元素,即cat,設定其鏈結欄位,使其指向mat的鏈結欄位(圖4.3)。


6522348

ptr

  • 圖4.3;從串列刪除mat


6522348

  • 函數create2建立了有兩個結點的鏈結函數。

    函數create2傳回first,為指向串列開始的指標。

  • 程式:建立有兩個節點的串列


6522348

ptr

  • 圖:有兩個節點的串列

  • 程式:在串列之前的簡易插入


6522348

  • 因為第二個指標node的位址不會改變,我們不需要將它的位址當作參數來傳送。典型的函數呼叫為insert (&ptr, node);其中ptr指向串列的開始,而node指向新的節點。

    對於空的串列,設定temp的鏈結點為NULL,並將ptr之值改成temp的位址。對於非空的串列,將節點temp插入node與其鏈結欄所指的節點之間。

    ptr

    node

    temp

  • 圖4.6:具有兩個節點的串列,在呼叫函數insert(&ptr, ptr);以後的串列


6522348

  • 圖4.7中刪除的結點試試串列的第一個節點。這表示我們必須確實的改變起始位址ptr。

    在圖4.8中,node不是第一個節點,我們只要改變trial的鏈結欄,使其指向node之鏈結欄所指的節點即可

    ptr node trail = NULL

    (a)刪除前

    ptr

    (b)刪除後

  • 圖4.7:呼叫函數delete( &per, NULL, ptr );以後的串列


6522348

ptr trial node

(a) 刪除前

ptr

(b) 刪除後

  • 呼叫函數delete( &ptr, ptr, ptr-> link );以後的串列


6522348

  • 函數delete從鏈結串列中刪除任意一個節點。除了改變鏈結欄,或*ptr之值以外,delete也會將配置給所刪除的節點之空間環給系統記憶體。要完成這件工作,使用free函數。

  • 程式:自串列中刪除


6522348

  • 4.6 鏈結堆疊與佇列

  • 程式:在鏈結的堆疊中加入元素

  • template <classT>

  • void LinkedStack <T>::Push(constT& e) {

  • top = new ChainNode <T>(e, top);

  • }


6522348

  • 程式:自鏈結的堆疊中刪除元素

  • template <class T>

  • voidLinkStack <T>::Pop( )

  • {// 刪除堆疊的頂端節點

  • if (IsEmpty()) throw “Stack is empty. Cannot delete.”;

  • ChainNode <T> *delNode = top;

  • top = top→link; // 移除頂端節點

  • deletedelNode; // 釋回此節點

  • }


6522348

  • 程式:在鏈結佇列的後端加入元素

  • template <class T>

  • voidLinkedQueue <T>::Push(constT& e)

  • {

  • if (IsEmpty( )) front = rear = newChainNode(e,0); //空佇列

  • elserear = rear→link = new ChainNode(e,0); // 連接節點並且更新rear

  • }


6522348

  • 程式:自鏈結佇列的前端刪除元素

  • template <class T>

  • voidLinkedQueue <T>:: Pop()

  • {// 刪除佇列的第一個元素

  • if (IsEmpty()) throw “Queue is empty. Cannot delete.”;

  • ChainNode<T> *delNode = front;

  • front = front→link; // 移除鏈的第一個節點

  • deletedelNode; // 釋回此節點

  • }


6522348

  • 4.7 多項式

  • 以單項鏈結串列來表示多項式

  • 我們可將多項式的每一項以一個節點表示,其中包含係數欄和指數欄,以及一個指向下一項的指標。假設係數均為整數,則其型態宣告為:

  • struct Term

  • {// 所有Term的成員都內定為公用的

  • int coef; // 係數

  • int exp; // 指數

  • Term Set(int c,int e) {coef = c;exp = e;return *this;};

  • };

  • classPolynomial {

  • public:

  • // 在這裡定義公用函式

  • private:

  • Chain<Term> poly;

  • };

  • 將Poly_node圖示如下:


6522348

  • 圖4.11表示如何儲存多項式         和

    a

    (a)

    b

    (b)

  • 圖4.11:多項式表示法


6522348

  • 多項式相加

  • 要將兩個多項式相加,先從a和b所指的節點開始檢查他們的項次:

    • 如果兩個項次的指數是相等的,則將係數相加,並為相加結果的多項式產生一個新的項目。

    • 如果在a中目前處理的項目之指數小於b中的,則複製b中的項目,並將其附加到結果多項式d中,而後將指標移到b的下一項。

    • 若a expon > b expon,則在a上採用類似的運算。

         a


6522348

d

  • a->expon == b-> expon

    a

    b

    d


6522348

(b) a -> expon < b -> expon

a

b

d

(c) a -> expon > b -> expon

  • 圖4.12:產生d=a+b結果的前三項


6522348

  • 每當 產生一個新的項目,我們要設定它的coef和expon欄位,並將他附加在d之後。為了避免每次加入的節點時必須找尋d的最後一個節點,我們使用一個指標rear來指向目前d中最後的一個節點。

  • 程式:兩個多項式相加

  • Polynomial Polynomial::operator+(constPolynomial& b) const

  • 2 {// 相加多項式 *this(a)與b並且回傳它們的和

  • 3 Term temp;

  • 4 Chain <Term>::ChainIterator ai = poly.begin(),

  • 5 bi =b. poly.begin();

  • 6 Polynomial c;

  • 7 while (ai&&bi) { // 目前的節點不是空的

  • 8 if (ai→exp = = bi→exp) {

  • 9 int sum = ai→coef + bi→coef;

  • 10 if (sum) c.poly.InsetBack (temp.Set(sum, ai→exp));

  • 11 ai++; bi++; // 前進至下一個項目

  • 12 }

  • 13 else if (ai→exp < bi→exp) {

  • 14 c.poly.InsertBack(temp.Set(bi→coef, bi→exp)) ;

  • 15 bi++; // b的下一個項目

  • 16 }


6522348

  • 17 else {

  • 18 c.poly.InsertBack(temp.Set(ai→coef , ai→exp)) ;

  • 19 ai++; // a的下一個項目

  • 20 }

  • 21 }

  • 22 while (ai) { // 複製a剩下的部份

  • 23 c.poly.InsertBack(temp.Set(ai→coef,ai→exp)) ;

  • 24 ai++;

  • 25 }

  • 26 while (bi) { // 複製b剩下的部份

  • 27 c.poly.InsertBack (temp.Set(bi→coef,bi→exp)) ;

  • 28 bi++ ;

  • 29 }

  • 29 returnc;

  • 30 }


6522348

  • 刪除多項式

  • 如果我們希望讀取多項式a(x), b(x), d(x),而後計算e(x)=a(x)*b(x)+d(x),他可能需要編寫許多的主函數,


6522348

  • 當我們需要計算更多的多項式時,回收用來儲存temp(x)的節點是很有幫助的。將temp(x)的節點釋回,我們也許會用到她們來儲存其他的多項式。

  • 以環狀鏈結串列表示法表示多項式

  • 如果我們修改串列的結構,使的最後一個節點的鏈結欄指向串列的第一個節點(如圖4.13),我們即可更有效率的釋回一個多項式的所有節點。我們稱其為環狀串列(circular list) 。單向鍊結串列的最後一個節點有虛鏈結時稱為鏈( chain ) 。

    ptr

  • 圖4.13:  的環狀表示法


6522348

  • 4.8 等價類

  • 定義:在集合S上的關係, ≡稱為在S上的等價關係(equivalence relation),若且惟若他在S上具有對稱性,反身性,和遞移性。

  • 舉例而言:

    如果有12個多邊形,編號為0到11,且下列各組重複:

    0 ≡ 4, 3 ≡ 1, 6 ≡ 10, 8 ≡ 9, 7 ≡ 4, 6 ≡ 8, 3 ≡ 5, 2 ≡ 11, 11 ≡ 0

    我們可將這些分割成下列的等價類:

    { 0,2,4,7,11 };{ 1,3,5 };{ 6,8,9,10 }


6522348

  • 判斷等價的演算法有兩個階段。在第一個階段中,我們讀取並儲存等價序對 < i, j >。

    在第二個階段中,由0開始找出所有形式為< 0, j >的序對。持續以這種方法工作,直到找出,標記,並印出整個也含0的等價類為止。而後繼續找出別的等價類。

  • 如果說有個陣列如:pairs[ n ][ m ]。這種方法可能會浪費許多的時間,因為只會用到少數的元素。而且這可能需要使用大量的時間將新的序對< i, k >插入列i。


6522348

[0]

[1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

[10]

[11]

data

11

3

11

5

7

3

8

4

6

8

6

0

link

0

0

0

0

0

0

data

4

1

0

10

9

2

link

0

0

0

0

0

0

  • 圖4.18:在序對輸入以後的串列

  • 分析等價程式:seq和out的設置需時O(n)。在第一階段輸入等價序對時,每一個序對需要一個常數時間。因此,這階段一共需要O(m+n)時間。


6522348

在第二階段,需要O(m+n)時間。所以,全部的計算為O(m+n)。


6522348

  • 4.9 稀疏矩陣

  • 在資料表示法中,稀疏矩陣的每一行以具有標頭節點的環狀鏈結串列表示。稀疏矩陣的每一列也有類似的表示法。

  • 每一個節點有一個標示欄位,他用來區別標頭節點與資料節點。

    每個標頭節點有3個欄位:down, right, next

    每個資料節點載標示欄位外還有5個欄位:row, col, down, righ, value

  • 如果ai j ≠ 0, 就有一個節點的標示欄為entry, value = aij, row = i, col = j

  • 每一個標頭節點出現在三個串列中;列串列,行串列,以及標頭節點串列。


6522348

down

head

right

next

down

head

row

col

right

entry

i

j

value

(a) 標頭節點 (b)資料節點      (c)設定aij

  • 圖4.19:稀疏矩陣節點構造

  • 圖4.20:4*4稀疏矩陣a


6522348

4

0

1

3

4

2

0

3

H1

H3

H2

H0

Matrix head

H0

11

  • 圖4.21:稀疏矩陣a的鏈結表示法

H1

12

2

1

H2

-4

H3

-15


6522348

  • 4.10 雙向鏈結串列

  • 如果指標指向一個特定點的節點ptr,而我們想要找到在ptr之前的節點。必須從串列的開頭找起,直到找到一個節點,其鏈結欄位指向ptr為止。

  • 對於刪除運算而言,因為我們必須知道前一個節點的位置,所以最有用的方法是使用雙向鏈結串列。

  • 在雙向鍊結串列中的節點至少有三個欄位,一個是左鏈結欄( llink ),一個是資料欄( item ),一個是右鍵欄位( rlink )。

  • 圖4.23中,標頭節點就像之前所說的一樣,可以使我們實作各種運算時較為容易。標頭節點的item欄通常不包含任何資訊。


6522348

rlink

item

llink

Head Node

  • 圖4.23:具有標頭節點的雙向鏈結環狀串列

    ptr

  • 圖4.24:具有標頭節點的空的雙向鏈結環狀串列

rlink

item

llink


6522348

node

node

  • 圖4.25:插入節點到空的雙向鏈結環狀串列

    delete

  • 圖4.26:從雙向鏈結環型串列中刪除

newnode

node

node


  • Login