Presentation is loading. Please wait.

Presentation is loading. Please wait.

第 3 章 堆疊與佇列.

Similar presentations


Presentation on theme: "第 3 章 堆疊與佇列."— Presentation transcript:

1 第 3 章 堆疊與佇列

2 目次 3.1 堆疊和佇列基本觀念 3.2 堆疊的加入與刪除 3.3 佇列的加入與刪除 3.4 其它形式的佇列 3.5 多個堆疊和多個佇列
3.1 堆疊和佇列基本觀念 3.2 堆疊的加入與刪除 3.3 佇列的加入與刪除 3.4 其它形式的佇列 3.5 多個堆疊和多個佇列 3.6 堆疊與佇列的應用 3.7 如何計算後序表示式 3.8 動動腦時間 3.9 練習題解答

3 3.1 堆疊和佇列基本觀念 堆疊(Stack) 加入(push)與刪除(pop)於同一端 後進先出(LIFO) 例子:堆積木、蓋房子

4 3.1 堆疊和佇列基本觀念(con.t) 佇列(Queue) 加入與刪除於不同端(front & rear) 先進先出(FIFO)
例子:排隊買票、坐公車

5 3.2 堆疊的加入與刪除 3.2.1 堆疊加入函數(top的初始值為-1)
3.2 堆疊的加入與刪除 堆疊加入函數(top的初始值為-1) void push_func(int stack[], int MAX, int top) { if (top >= MAX-1) /* 當堆疊已滿,則顯示錯誤 */ printf("Stack is full !"); else { top++; printf( “\n\n Please enter item to insert: "); scanf( "%d", &stack[top]); }

6 3.2 堆疊的加入與刪除(con.t) 3.2.2 堆疊刪除函數 void pop_func(int stack[], int top) {
if (top < 0) /* 當堆疊沒有資料存在,則顯示錯誤 */ printf(“\n\n No item, stack is empty !\n"); else { printf("\n\n Item %d deleted\n", stack[top]); top --; }

7 3.3 佇列的加入與刪除 3.3.1 佇列加入函數(front、rear的初始值分別為0、-1)
3.3 佇列的加入與刪除 3.3.1 佇列加入函數(front、rear的初始值分別為0、-1) void enqueue_func(int q[], int MAX, int rear) { if (rear >= MAX-1) /* 當佇列已滿,則顯示錯誤 */ printf("\n\nQueue is full !\n"); else { rear++; printf("\n\n Please enter item to insert: "); scanf("%d",&q[rear]); }

8 3.3 佇列的加入與刪除(con.t) 3.3.2 佇列刪除函數
void dequeue_func(int q[], int front, int rear) { if (front > rear) /* 當資料沒有資料存在,則顯示錯誤 */ printf("\n\n No item, queue is empty !\n"); else { printf("\n\n Item %d deleted\n", q[front]); front++; }

9 3.3 佇列的加入與刪除(con.t) 問題 環狀佇列 佇列前端還有空位,但要加入元素卻發現此佇列已滿 圖3-2 環狀佇列 1 2 3 4
1 2 3 4 5 6 7 8 N-1 N-2 圖3-2 環狀佇列

10 3.3 佇列的加入與刪除(con.t) 3.3.3 環狀佇列加入函數(front、rear的初始值均為MAX-1) {
void enqueue_func(int cq[], int MAX, int front, int rear) { rear = (rear + 1) % MAX; if (front == rear) { if (rear == 0) rear = MAX–1 ; /* 退回原位 */ else rear = rear–1 ; /* 退回原位 */ printf("\n\nQueue is full!\n"); } else { printf("\n\n Please enter item to insert: "); scanf("%d",&cq[rear]);

11 3.3 佇列的加入與刪除(con.t) 3.3.4 環狀佇列刪除函數
void dequeue_func(int cq[], int MAX, int front, int rear) { if (front == rear) printf("\n\n Queue is empty !\n"); else { front = (front + 1) % MAX; printf("\n\n Item %d deleted\n", cq[front]); }

12 3.4 其它形式的佇列 雙向佇列(deque) 優先權佇列(priority queue) Double-ended queue
3.4 其它形式的佇列 雙向佇列(deque) Double-ended queue 佇列的兩端皆可加入和刪除 Ex:循序輸入五筆資料(1、2、3、4、5) 優先權佇列(priority queue) 每筆資料是依照優先權的高低放在佇列的適當位置 優先權高,所在的位置愈前面(愈快被執行) Ex:Heap

13 3.5 多個堆疊與多個佇列 與單一堆疊和佇列的觀念大致相同 多個堆疊的加入、刪除也是在同一端 多個佇列的加入是在後端、刪除是在前端
3.5 多個堆疊與多個佇列 與單一堆疊和佇列的觀念大致相同 多個堆疊的加入、刪除也是在同一端 多個佇列的加入是在後端、刪除是在前端 Ex:公司將硬碟空間分割成多個部份給員工來使用 多個佇列的形狀圖 多個堆疊的形狀圖

14 3.5 多個堆疊與多個佇列(con.t) 3.5.1 多個堆疊加入函數 (課本圖3.3)
void push_func (int MS[ ], int t[ ], int b[ ], int i ) { if (t[i-1] == b[i]) printf(“stack is full !!!”); else MS[++t[i-1]] = x; }

15 3.5 多個堆疊與多個佇列(con.t) 3.5.2 多個堆疊刪除函數 { if (t[i-1] == b[i-1]){
void pop_func (int MS[ ], int t[ ], int b[ ], int i, int x) { if (t[i-1] == b[i-1]){ printf(“stack is empty !!”); return 0; } else{ x = MS[t[i-1]--] ; print(“%d is deleted !!!”, x);

16 3.5 多個堆疊與多個佇列(con.t) 3.5.3 多個佇列加入函數 (課本圖3.4) void enqueue_func (int MQ[ ], int f[ ], int r[ ], int i, int x) { if (r[i-1] == f[i]) printf(“queue is full !!!”); else MQ[++r[i-1]] = x; }

17 3.5 多個堆疊與多個佇列(con.t) 3.5.4 多個堆疊刪除函數 { if (r[i-1] == f[i-1]){
void dequeue_func (int MQ[ ], int f[ ], int r[ ], int i, int x) { if (r[i-1] == f[i-1]){ printf(“queue is empty !!”); return 0; } else{ x = MQ[f[i-1]++] ; print(“%d is deleted !!!”, x);

18 3.6 堆疊與佇列的應用 堆疊的應用 佇列的應用 副程式的呼叫 (subroutine calls) 中序表示式 → 後序表示式
3.6 堆疊與佇列的應用 堆疊的應用 副程式的呼叫 (subroutine calls) 中序表示式 → 後序表示式 佇列的應用 作業系統的工作安排(job scheduling)

19 3.6 堆疊與佇列的應用(con.t) 中序表示式 後序表示式 「運算子」(operator)置於「運算元」(operand)的中間
Ex:A*B / C 後序表示式 「運算子」置於「運算元」的後面 Ex:AB * C /

20 3.6 堆疊與佇列的應用(con.t) 一般運算子的運算優先順序如下: 運算子 優先順序(數字愈大,優先順序愈高) * , / , % 5
運算子 優先順序(數字愈大,優先順序愈高) * , / , % + (加), - (減) <, <= , > , >= && ||

21 3.6 堆疊與佇列的應用(con.t) 運用堆疊的觀念 符號 in-stack priority in-coming priority
) – – * , / , % + (加), - (減) (

22 3.6 堆疊與佇列的應用(con.t) void infix_to_postfix(char infix_q[], int rear) {
int top = 0, ctr; char stack_t[MAX]; /* 用以儲存還不必輸出的運算子 */ stack_t[top] = '#'; /* 於堆疊最底下加入#為結束符號 */ for(ctr = 0; ctr <= rear; ctr++) { switch(infix_q[ctr]) { /* 輸入為),則內輸出堆疊內運算子,直到堆疊內為( */ case ')': while(stack_t[top] != '(') printf("%c", stack_t[top--]); top--; break; /* 輸入為#,則將堆疊內還未輸出的運算子輸出 */ case '#': while(stack_t[top] != '#')

23 3.6 堆疊與佇列的應用(con.t) /* 輸入為運算子,若小於TOP在堆疊中所指運算子,則將堆疊所指運算子輸
case '(': case '^': case '*': case '/': case '+': case '-': while(compare(stack_t[top], infix_q[ctr])) printf("%c", stack_t[top--]); stack_t[++top] = infix_q[ctr]; break; /* 輸入為運算元,則直接輸出 */ default : printf("%c", infix_q[ctr]); }

24 3.6 堆疊與佇列的應用(con.t) /* 比較兩運算子優先權,若輸入運算子小於堆疊中運算子,則傳值為1,否則為0 */
int compare(char stack_o, char infix_o) { int index_s = 0, index_i = 0; while(stack_priority[index_s] != stack_o) index_s++; while(infix_priority[index_i] != infix_o) index_i++; return index_s/2 >= index_i/2 ? 1 : 0; }

25 3.7 如何計算後序表示式 步驟 1:先將後序表示式以一字串表示 步驟 2:每次取出一個token,若
3.7 如何計算後序表示式 步驟 1:先將後序表示式以一字串表示 步驟 2:每次取出一個token,若 token為運算元,則將它push至堆疊中 token為運算子,則從堆疊中pop出二個運算元,並做適當的運算 token為’0’,則跳到步驟四 步驟 3:將步驟2的結果再push至堆疊,並繼續執行 步驟2。 步驟 4:彈出堆疊的資料,此資料即為後序表示法計 算的結果


Download ppt "第 3 章 堆疊與佇列."

Similar presentations


Ads by Google