The C Programming Language

Download Report

Transcript The C Programming Language

鏈結串列
(Linked List)
CSIM, PU
C Language
1
指標
 在指標類型中,兩種重要的運算子:
 & :位址運算子,用來取得變數的記憶體位址。
 * :取值運算子,用來取得指標所指向變數的內容
 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
2
動態記憶體配置---malloc函數
 動態記憶體配置指的是在執行階段才向作業系統要求
配置記憶體空間。
 在C語言中,每次呼叫 malloc()函數,就會取得一塊
可用的記憶體空間。
malloc函數配置失敗時會傳回一個空指標。
 用法:
fp = (資料型態*) malloc(sizeof(資料型態));
型別轉換,將malloc函數傳回的
指標轉成符合配置的資料型態
算出所需的記憶體空間大小
fp = (float*)malloc(sizeof(float));
配置一塊 float 的記憶體空間,指標 fp 指向此空間
CSIM, PU
C Language
3
動態記憶體配置---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
4
動態記憶體配置---free函數
 free函數可將已配置的記憶體空間歸還。
 用法:
free(fp);
 範例:
int main()
{
float *fp;
fp=(float *)malloc(sizeof(float));
if(fp==NULL)
printf(“記憶體配置失敗\n”);
free(fp);
}
CSIM, PU
C Language
5
單向鏈結串列
單向鏈結串列是由節點(node)所串成的串列,如下圖所示。
ptr
bat
‧
cat
‧
vat
‧
sat
NULL
指向第ㄧ個節點的指標名稱(ptr)為此鏈結串列的名稱。
在單向鏈結串列中每個節點都包含兩個欄位:
 資料欄位:存放資料的地方
 鏈結欄位:指向下一個 node
Data
Link
單向鏈結串列的節點結構
CSIM, PU
C Language
6
單向鏈結串列
可使用自我參考結構(self-referential structure)來定義節點
結構,如下:
typedef struct node
{
定義節點結構
int data;
struct node *link;
} nodes;
ptr為node結構的指標 nodes *ptr;
 可使用malloc函數來建立新節點,如下:
ptr=(nodes *)malloc(sizeof(nodes));
配置一塊記憶體空間
為指標,指向另ㄧ個node結構
ptr
data
CSIM, PU
link
C Language
7
練習
#include<stdio.h>
int main()
{
typedef struct node {
int data;
struct node *link;
}nodes;
ptr
10
null
data
link
nodes *ptr;
ptr =(nodes *)malloc(sizeof(nodes));
ptr->data=10;
ptr->link=NULL;
printf("第一個數= %d\n",ptr->data);
}
CSIM, PU
C Language
8
練習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
10
null
data
link
20
null
data
link
first
ptr->data=10;
ptr->link=NULL;
first->data=20;
first->link=NULL;
printf("第一個數= %d\n",ptr->data);
printf(“第二個數= %d\n",first->data);
}
CSIM, PU
C Language
9
單向鏈結串列
 程式範例:
#include<stdio.h>
int main()
{
ptr
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);
}
CSIM, PU
first
20
10
data
link
data
C Language
link
10
單向鏈結串列-加入串列前端
一. 加入於串列的前端
ptr
NULL
x
typedef struct node
{
int data;
struct node *link;
}nodes;
nodes *x;
步驟如下:
(1)x=(nodes *) malloc (sizeof(nodes));
(2)x→link=ptr;
(3)ptr=x;
CSIM, PU
/*配置記憶體空間*/
/*將x節點的point指到剛head的地方*/
/*head換指到x節點(前端變成x節點)*/
C Language
11
練習3-加入節點於串列前端
 請將下方(1)鏈結串列,改成(2)鏈結串列。
first
ptr
(1)
20
10
data
link
data
first
ptr
(2)
CSIM, PU
data
20
10
5
x
link
link
data
link
data
link
C Language
12
單向鏈結串列-加入串列尾端
二. 加入於串列的尾端
head
NULL
next
x
null
步驟如下:
(1)x=(nodes *) malloc (sizeof(nodes));
x->link=NULL;
(2)next=head
while(next->link!=NULL)
next=next->link;
next->link=x;
CSIM, PU
C Language
13
練習4-加入節點於串列尾端
 請將下方(1)鏈結串列,改成(2)鏈結串列。
ptr
(1)
data
20
10
5
data
link
link
data
link
y
ptr
(2)
data
CSIM, PU
20
10
5
link
data
link
data
30
link
data
C Language
link
14
單向鏈結串列-加入某一節點之後
三. 加入在串列某一特定節點(add節點)的後面
add
ptr
NULL
x
步驟如下:
(1)x=(nodes *) malloc (sizeof(nodes));
(2)x→link=add→link;
(3)add→link=x;
CSIM, PU
C Language
15
單向鏈結串列-刪除串列前端
一. 刪除串列前端的節點
ptr
ptr
NULL
temp
步驟如下:
(1)temp=ptr;
(2)ptr=ptr->link;
(3)free(temp);
CSIM, PU
C Language
16
練習5-刪除前端節點
 請將下方(1)鏈結串列,改成(2)鏈結串列。
ptr
(1)
data
20
10
5
data
link
link
data
30
link
data
link
ptr
(2)
data
CSIM, PU
20
10
link
data
30
link
data
link
C Language
17
單向鏈結串列-刪除串列最後節點
二. 刪除串列的最後節點
prev
ptr
NULL
步驟如下:
NULL
temp
(1) temp=ptr;
while(temp->link!=NULL)
{
prev=temp;
temp=temp->link;
}
(2) prev->link=NULL;
(3) free(temp);
CSIM, PU
C Language
18
單向鏈結串列-刪除某一節點
三. 刪除某一特定的節點
prev
this
ptr
NULL
步驟如下:
(1)必須先用兩個指標this和prev,分別指到即將被刪除節點及前一節點。
(2)prev->link=this->link;
(3) free(this);
CSIM, PU
C Language
19
計算單向鏈結串列之長度
串列長度指的是此串列共有多少個節點,只要指標指到的
節點非NULL,則利用一變數做累加,直到指標到NULL為止
。
int length (struct node *ptr )
{
struct node *this;
this=ptr;
int leng=0;
while (this != NULL)
{
leng ++;
this=this->link;
}
return leng ;
}
CSIM, PU
C Language
20
二、環狀串列
一. 定義:將單向鏈結串列最後一個node的指標指回第
一個node。
二. 特色:不論從哪一節點開始尋找,都能夠經過串列
中所有節點。
CSIM, PU
C Language
21
三、雙向鏈結串列
1.每個節點皆有三個欄位,一為左鏈結(LLINK),二為資料
(DATA),三為右鏈結(RLINK),其中LLINK指向前一個節點,而
RLINK指向後一個節點。
LLINK
DATA
RLINk
2.通常在雙向鏈結串列中會加上一個串列首。
此串列首的資料欄不存任何資料。
串列首
CSIM, PU
C Language
22
雙向鏈結串列的優缺點
優點:
 加入/刪除任何一個節點時,無需知道其前一節點的位址
 可由任何一個節點立即找到前一個或後一個節點
 從任何ㄧ個節點開始,必可經過串列中所有nodes
缺點:
 增加一個指標空間,需要更多記憶體
 新加入ㄧ個節點時需改變四個指標,而單向鏈節串列只需改
變兩個指標
 刪除時需改變兩個指標,而單向只要改變一個指標
CSIM, PU
C Language
23
四、多項式的表示
利用鏈結串列來表示多項式:
COEF EXP
Ex:
23
CSIM, PU
LINK
f  x   23 x  12 x  11
3
3
其中COEF表示變數的係數
EXP表示變數的指數
LINK為指到下一節點的指標
用鏈結串列來表示 ,
12
1
11
0
NULL
C Language
24
多項式的相加
 假設兩個多項式
A  3x
14
 2x  1
8
與
B  8x
14
 3x
10
 10 x
6
相加
 以單向鏈結串列方式呈現,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;
CSIM, PU
C Language
25
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
26
if (ptr->coef != 0)
{
if (ans_h = = NULL)
ans_h = ptr;
else
prev -> link = ptr;
prev = ptr;
}
else
free (ptr);
}
}
CSIM, PU
C Language
27
五、使用鏈結串列製作堆疊
加入一個節點於堆疊中,由於堆疊的運作都在同一端,因此可將
它視為將節點加入於串列的前端。
ptr
堆疊加入演算法
void push(int num , nodes *ptr , nodes *top)
{
ptr = (nodes *)malloc(sizeof(nodes));
ptr->data=num;
ptr->link=top;
top=ptr;
}
CSIM, PU
top
num
null
C Language
28
刪除堆疊頂端的頂點:其運作類似刪除串列的前端節點。
刪除資料的演算法
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);
}
CSIM, PU
top
clear
top
C Language
29
六、使用鏈結串列製作佇列
佇列的加入
void AddQ(int num , nodes *front , nodes *rear)
{
nodes *ptr;
ptr = (nodes *)malloc(sizeof(nodes));
front
ptr->data=num;
ptr->next=NULL;
if(rear==NULL)
front=rear=ptr;
else
{
rear->link=ptr;
rear=ptr;
rear
}
}
CSIM, PU
ptr
null
num null
rear
C Language
30
六、使用鏈結串列製作佇列
佇列的刪除
void DeleteQ(int num , nodes *front)
{
clear
nodes *clear;
if (front==NULL)
front
{
printf(“queue empty”);
return;
}
num=front->data;
clear=front;
front=front->link;
rear
null
free(clear);
}
CSIM, PU
C Language
31