鏈結串列 (linked list)

31
CSIM, PU C Language 1 鏈鏈鏈鏈 (Linked List)

Upload: rae

Post on 11-Jan-2016

99 views

Category:

Documents


0 download

DESCRIPTION

鏈結串列 (Linked List). 指 標. 在指標類型中,兩種重要的運算子: & : 位 址運算子,用來取得變數的記憶體位址。 * : 取值運算子,用來取得指標所指向變數的內容 null 指標代表此指標不指向任何物件或函數 可用 0 來表示 null 指標。. 例如: if (pi == NULL) printf(“It’s a empty pointer\n”); 可寫成 if (!pi) - PowerPoint PPT Presentation

TRANSCRIPT

CSIM, PU C Language 1

鏈結串列(Linked List)

CSIM, PU C Language 2

指 標 在指標類型中,兩種重要的運算子:

& : 位址運算子,用來取得變數的記憶體位址。 * : 取值運算子,用來取得指標所指向變數的內容

null 指標代表此指標不指向任何物件或函數 可用 0 來表示 null 指標。

例如: if (pi == NULL) printf(“It’s a empty pointer\n”);可寫成 if (!pi) printf(“It’s a empty pointer\n”); /* pi=0(false) , !pi=1(true) ,所以執行 printf */

CSIM, PU C Language 3

動態記憶體配置 ---malloc函數動態記憶體配置指的是在執行階段才向作業系統要求配置記憶體空間。

在 C 語言中,每次呼叫 malloc() 函數,就會取得一塊可用的記憶體空間。

malloc 函數配置失敗時會傳回一個空指標。用法:

fp = (float*)malloc(sizeof(float));

算出所需的記憶體空間大小fp = ( 資料型態 *) malloc(sizeof( 資料型態 ));

型別轉換,將 malloc 函數傳回的指標轉成符合配置的資料型態

配置一塊 float 的記憶體空間,指標 fp 指向此空間

CSIM, PU C Language 4

動態記憶體配置 ---malloc函數範例:

#include<stdio.h>

int main()

{

float *fp;

fp=(float *)malloc(sizeof(float));

if(fp!=NULL)

{

*fp=3.14;

printf(“ 數字 =%f\n”,*fp);

}

else

printf(“ 記憶體配置失敗 !\n”);

}

CSIM, PU C Language 5

動態記憶體配置 ---free函數 free 函數可將已配置的記憶體空間歸還。用法:

範例:free(fp);

int main(){ float *fp; fp=(float *)malloc(sizeof(float)); if(fp==NULL) printf(“ 記憶體配置失敗 \n”); free(fp);}

CSIM, PU C Language 6

單向鏈結串列單向鏈結串列是由節點 (node) 所串成的串列,如下圖所示。

bat ‧ cat ‧ sat NULLvat ‧ptr

指向第ㄧ個節點的指標名稱 (ptr) 為此鏈結串列的名稱。在單向鏈結串列中每個節點都包含兩個欄位:

資料欄位:存放資料的地方鏈結欄位:指向下一個 node

Data Link

單向鏈結串列的節點結構

CSIM, PU C Language 7

單向鏈結串列可使用自我參考結構 (self-referential structure) 來定義節點結構,如下:

data link

為指標,指向另ㄧ個 node 結構

ptr

定義節點結構

可使用 malloc 函數來建立新節點,如下:

typedef struct node { int data;

struct node *link;} nodes;nodes *ptr;

ptr 為 node 結構的指標

配置一塊記憶體空間

ptr=(nodes *)malloc(sizeof(nodes));

CSIM, PU C Language 8

練習#include<stdio.h>int main(){ typedef struct node { int data; struct node *link; }nodes;

nodes *ptr; ptr =(nodes *)malloc(sizeof(nodes));

ptr->data=10; ptr->link=NULL;

printf(" 第一個數 = %d\n",ptr->data);}

data link

ptr

10 null

CSIM, PU C Language 9

練習 2

#include<stdio.h>int main(){ typedef struct node { int data; struct node *link; }nodes;

nodes *ptr, *first; ptr =(nodes *)malloc(sizeof(nodes)); first =(nodes *)malloc(sizeof(nodes));

ptr->data=10; ptr->link=NULL;

first->data=20; first->link=NULL; printf(" 第一個數 = %d\n",ptr->data);

printf(“ 第二個數 = %d\n",first->data);

}

data link

ptr

10 null

data link

first

20 null

CSIM, PU C Language 10

單向鏈結串列程式範例:

#include<stdio.h>int main(){ typedef struct node { int data; struct node *link; }nodes; nodes *ptr, *first; ptr =(nodes *)malloc(sizeof(nodes)); first = (nodes *)malloc(sizeof(nodes)); ptr->data=10; first->data=20; ptr->link=first; printf(" 第一個數 = %d\n",ptr->data); printf(" 第二個數 = %d\n",ptr->link->data);}

data link

ptr

data link

first

10 20

CSIM, PU C Language 11

單向鏈結串列 - 加入串列前端.壹 加入於串列的前端

typedef struct node { int data; struct node *link; }nodes;

nodes *x;

步驟如下:(1)x=(nodes *) malloc (sizeof(nodes)); /* 配置記憶體空間 */ (2)x→link=ptr; /* 將 x 節點的 point 指到剛 head的地方 */

(3)ptr=x; /*head 換指到 x 節點 ( 前端變成 x 節點 )*/

NULL

ptr

x

CSIM, PU C Language 12

練習 3-加入節點於串列前端 請將下方 (1) 鏈結串列,改成 (2) 鏈結串列。

data link

ptr

data link

first

10 20

data link

ptr

data link

first

10 20

data link

5

x

(1)

(2)

CSIM, PU C Language 13

單向鏈結串列 - 加入串列尾端.貳 加入於串列的尾端

步驟如下:(1)x=(nodes *) malloc (sizeof(nodes)); x->link=NULL;(2)next=head while(next->link!=NULL) next=next->link; next->link=x;

NULL

head

next

x

null

CSIM, PU C Language 14

練習 4-加入節點於串列尾端 請將下方 (1) 鏈結串列,改成 (2) 鏈結串列。

(1)

(2)

data link

ptr

data link

10 20

data link

5

data link

ptr

data link

10 20

data link

5

data link

30

y

CSIM, PU C Language 15

單向鏈結串列 - 加入某一節點之後.參 加入在串列某一特定節點 (add節點 ) 的後面

步驟如下:(1)x=(nodes *) malloc (sizeof(nodes));(2)x→link=add→link;(3)add→link=x;

add

NULL

ptr

x

CSIM, PU C Language 16

.壹 刪除串列前端的節點

單向鏈結串列 - 刪除串列前端

步驟如下:

(1)temp=ptr; (2)ptr=ptr->link; (3)free(temp);

NULL

ptr

temp

ptr

CSIM, PU C Language 17

練習 5-刪除前端節點 請將下方 (1) 鏈結串列,改成 (2) 鏈結串列。

(1)

(2)

data link

ptr

data link

10 20

data link

5

data link

30

data link data link

10 20

data link

30

ptr

CSIM, PU C Language 18

.貳 刪除串列的最後節點

單向鏈結串列 - 刪除串列最後節點

步驟如下:(1) temp=ptr;

while(temp->link!=NULL)

{

prev=temp;

temp=temp->link;

}

(2) prev->link=NULL;

(3) free(temp);

ptrNULL NULL

temp

prev

CSIM, PU C Language 19

.參 刪除某一特定的節點單向鏈結串列 - 刪除某一節點

步驟如下:(1) 必須先用兩個指標 this 和 prev,分別指到即將被刪除節點及前一節點。

(2)prev->link=this->link;

(3) free(this);

NULL

ptrthisprev

CSIM, PU C Language 20

計算單向鏈結串列之長度

int length (struct node *ptr )

{ struct node *this;

this=ptr;

int leng=0; while (this != NULL) {

leng ++;

this=this->link; } return leng ;

串列長度指的是此串列共有多少個節點,只要指標指到的節點非 NULL,則利用一變數做累加,直到指標到 NULL為止。

CSIM, PU C Language 21

二、環狀串列.壹 定義:將單向鏈結串列最後一個 node的指標指回第一個 node。

.貳 特色:不論從哪一節點開始尋找,都能夠經過串列中所有節點。

CSIM, PU C Language 22

三、雙向鏈結串列

1.每個節點皆有三個欄位,一為左鏈結 (LLINK),二為資料(DATA),三為右鏈結 (RLINK),其中 LLINK指向前一個節點,而 RLINK指向後一個節點。

2.通常在雙向鏈結串列中會加上一個串列首。 此串列首的資料欄不存任何資料。

LLINK DATA RLINk

串列首

CSIM, PU C Language 23

優點:① 加入 / 刪除任何一個節點時,無需知道其前一節點的位址② 可由任何一個節點立即找到前一個或後一個節點③ 從任何ㄧ個節點開始,必可經過串列中所有 nodes

缺點:① 增加一個指標空間,需要更多記憶體② 新加入ㄧ個節點時需改變四個指標,而單向鏈節串列只需改

變兩個指標③ 刪除時需改變兩個指標,而單向只要改變一個指標

雙向鏈結串列的優缺點

CSIM, PU C Language 24

四、多項式的表示

利用鏈結串列來表示多項式:

Ex: 用鏈結串列來表示 ,

COEF EXP LINK

111223 3 xxxf

23 3 12 1 11 0 NULL

其中 COEF 表示變數的係數EXP 表示變數的指數LINK 為指到下一節點的指標

CSIM, PU C Language 25

多項式的相加

假設兩個多項式 與 相加

以單向鏈結串列方式呈現, C 語言片段程式如下:

void poly_add(struct poly *eql, struct poly *eq2, struct poly *ans_h, struct poly *ptr)

{

struct poly *thisl, *this2, *prev;

this1 = eq1;

this2 = eq2;

prev = NULL;

while(this1 != NULL || this2 != NULL)

{

ptr = (struct poly*) malloc(sizeof(struct poly));

ptr ->link = NULL;

61014 1038 xxxB 123 814 xxA

CSIM, PU C Language 26

第ㄧ個多項式指數大於第二個多項式

第ㄧ個多項式指數小於第二個多項式

if (this1 != NULL && (this2 = = NULL | | this1->exp > this2 ->exp)){ ptr->coef = this1->coef; ptr->exp = this1->exp; this1 = this1->next;}else if (this1 == NULL || this1->exp < this2 ->exp){ ptr->coef = this2->coef; ptr->exp = this2->exp; this2 = this2->link; } else{

ptr->coef = this1->coef + this2->coef; ptr->exp = this1->exp; if (this1 != NULL) this1 = this1->link; if (this1 != NULL) this2 = this2->link;

}

兩個多項式指數相等,進行相加

CSIM, PU C Language 27

if (ptr->coef != 0){ if (ans_h = = NULL) ans_h = ptr; else prev -> link = ptr; prev = ptr;}else free (ptr);

}}

CSIM, PU C Language 28

五、使用鏈結串列製作堆疊

堆疊加入演算法

void push(int num , nodes *ptr , nodes *top)

{

ptr = (nodes *)malloc(sizeof(nodes));

ptr->data=num;

ptr->link=top;

top=ptr;

}

加入一個節點於堆疊中,由於堆疊的運作都在同一端,因此可將它視為將節點加入於串列的前端。

null

top

ptr

num

CSIM, PU C Language 29

刪除資料的演算法 void pop(int num , nodes *top){ nodes *clear; if(top==NULL) { printf(“stack is empty”); return; } clear=top; num=top->data; top=top->link; free(clear);}

刪除堆疊頂端的頂點:其運作類似刪除串列的前端節點。

top clear

top

CSIM, PU C Language 30

六、使用鏈結串列製作佇列佇列的加入void AddQ(int num , nodes *front , nodes *rear){ nodes *ptr; ptr = (nodes *)malloc(sizeof(nodes)); ptr->data=num; ptr->next=NULL; if(rear==NULL) front=rear=ptr; else { rear->link=ptr; rear=ptr; }}

null

front

rear

ptr

num nullrear

CSIM, PU C Language 31

六、使用鏈結串列製作佇列佇列的刪除void DeleteQ(int num , nodes *front)

{

nodes *clear;

if (front==NULL)

{

printf(“queue empty”);

return;

}

num=front->data;

clear=front;

front=front->link;

free(clear);

}

null

front

rear

clear