鏈結串列 (Linked List)
description
Transcript of 鏈結串列 (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 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