鏈結串列 (linked list)

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

Upload: mikayla-mccray

Post on 03-Jan-2016

36 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

Page 1: 鏈結串列 (Linked List)

CSIM, PU C Language 1

鏈結串列(Linked List)

Page 2: 鏈結串列 (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”);

Page 3: 鏈結串列 (Linked List)

CSIM, PU C Language 3

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

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

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

指標變數 =( 指標變數所指向的型態 *) malloc( 所需的記憶空間 )

將 malloc() 所傳回的位址強制轉換成指標變數所指向的型態

Page 4: 鏈結串列 (Linked List)

CSIM, PU C Language 4

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

int *ptr;

ptr=(int *) malloc(12); // 配置 3*4-12Bytes 記憶空間,並把 ptr 指向它 例二:

int *ptr;

ptr=(int *) malloc(3*sizeof(int)); // 配置可存放 3 個整數的記憶空間

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

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

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

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

Page 5: 鏈結串列 (Linked List)

CSIM, PU C Language 5

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

#include<stdio.h>

#include<stdlib.h>

int main()

{ float *fp;

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

if(fp!=NULL)

{

*fp=3.14;

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

}

else

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

}

Page 6: 鏈結串列 (Linked List)

CSIM, PU C Language 6

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

範例:free( 指標變數 );

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

Page 7: 鏈結串列 (Linked List)

CSIM, PU C Language 7

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

bat ‧ cat ‧ sat NULLvat ‧ptr

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

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

Data Link

單向鏈結串列的節點結構

Page 8: 鏈結串列 (Linked List)

CSIM, PU C Language 8

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

data link

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

ptr

定義節點結構

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

typedef struct node SN;struct node { int data; SN *link;} ;SN *ptr;

ptr 為 node 結構的指標

配置一塊記憶體空間

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

Page 9: 鏈結串列 (Linked List)

CSIM, PU C Language 9

單向鏈結串列程式範例:

#include<stdio.h>int main(){ typedef struct node SN; struct node { int data; SN *link; }; SN *ptr, *first; ptr =(SN *)malloc(sizeof(SN)); first = (SN *)malloc(sizeof(SN)); 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

Page 10: 鏈結串列 (Linked List)

CSIM, PU C Language 10

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

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

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

NULL

ptr

x

Page 11: 鏈結串列 (Linked List)

CSIM, PU C Language 11

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

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

NULLhead

next x null

Page 12: 鏈結串列 (Linked List)

CSIM, PU C Language 12

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

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

add

NULL

ptr

x

Page 13: 鏈結串列 (Linked List)

CSIM, PU C Language 13

.壹 刪除串列前端的節點

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

步驟如下:

(1)temp=ptr;

(2)ptr=ptr->link;

(3)free(temp);

NULL

ptr

temp

ptr

Page 14: 鏈結串列 (Linked List)

CSIM, PU C Language 14

.貳 刪除串列的最後節點

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

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

while(temp->link!=NULL)

{

prev=temp;

temp=temp->link;

}

(2) prev->link=NULL;

(3) free(temp);

ptrNULL NULL

temp

prev

Page 15: 鏈結串列 (Linked List)

CSIM, PU C Language 15

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

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

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

(3) free(this);

NULL

ptrthisprev

Page 16: 鏈結串列 (Linked List)

CSIM, PU C Language 16

計算單向鏈結串列之長度

int length (struct node *ptr )

{ struct node *this;

this=ptr;

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

leng ++;

this=this->link; } return leng ;

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

Page 17: 鏈結串列 (Linked List)

CSIM, PU C Language 17

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

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

Page 18: 鏈結串列 (Linked List)

CSIM, PU C Language 18

三、雙向鏈結串列

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

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

LLINK DATA RLINk

串列首

Page 19: 鏈結串列 (Linked List)

CSIM, PU C Language 19

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

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

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

雙向鏈結串列的優缺點

Page 20: 鏈結串列 (Linked List)

CSIM, PU C Language 20

四、多項式的表示

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

Ex: 用鏈結串列來表示 ,

COEF EXP LINK

111223 3 xxxf

23 3 12 1 11 0 NULL

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

Page 21: 鏈結串列 (Linked List)

CSIM, PU C Language 21

多項式的相加

假設兩個多項式 與 相加

以單向鏈結串列方式呈現, 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

Page 22: 鏈結串列 (Linked List)

CSIM, PU C Language 22

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

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

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;

}

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

Page 23: 鏈結串列 (Linked List)

CSIM, PU C Language 23

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

}}

Page 24: 鏈結串列 (Linked List)

CSIM, PU C Language 24

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

堆疊加入演算法

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

{

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

ptr->data=num;

ptr->link=top;

top=ptr;

}

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

null

top

ptr

num

Page 25: 鏈結串列 (Linked List)

CSIM, PU C Language 25

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

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

top clear

top

Page 26: 鏈結串列 (Linked List)

CSIM, PU C Language 26

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

null

front

rear

ptr

num nullrear

Page 27: 鏈結串列 (Linked List)

CSIM, PU C Language 27

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

{

node *clear;

if (front==NULL)

{

printf(“queue empty”);

return;

}

num=front->data;

clear=front;

front=front->link;

free(clear);

}

null

front

rear

clear