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