第三章 堆疊與佇列的基本應用 3-1 簡介堆疊(Stack) 3-2 迷宮問題研究 3-3 佇列(queue)的介紹

Slides:



Advertisements
Similar presentations
图形的平移 苏科版教材七年级下册第八章第三节 镇江市第三中学 李萌. 南京 江南大酒店 南京江南大酒店,三星级,位于南京市中央路与 新模范马路的交汇处,六层,建筑面积 5424 m 2 , 总重量 8000 t 。 2001 年马路拓宽,这幢楼在拓宽的范围内,将 这样的一个星级酒店拆掉有点可惜,要是能将整幢大.
Advertisements

迷 宫 最短路径 施沈翔.
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
動畫與遊戲設計 Data structure and artificial intelligent
江苏省2008年普通高校 招生录取办法 常熟理工学院学生处
高考新改革与过渡 怀化市铁路第一中学 向重新.
資料結構與C++程式設計進階 資料結構概論 講師:林業峻 CSIE, NTU 6/ 7, 2010.
書名 Java於資料結構與演算法之實習應用
江苏省2009年普通高校 招生录取办法 江苏省教育考试院
第3章 栈和队列 3.1 栈 3.2 队列 3.3 应用.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
C语言程序设计 第十二章 位运算.
高级语言程序设计 主讲人:陈玉华.
主讲教师:吴琼 微信群:C语言2016 QQ群: 密码scu2016 昵称:“真名+学号”
佇列 (Queue).
佇列與推疊 (Queue and Stack)
資料結構簡介.
資料結構 第5章 佇列.
C++程序设计 第二讲 清华大学软件学院.
Chap 3 堆疊與佇列 Stack and Queue.
C程序设计.
QQ: 李祥 QQ: 欢迎多种方式的学习交流,祝大家学有所成.
第十五章 Linked List, Stack and Queue
4 堆疊與佇列 4.1 前言 四種基本的資料結構 (可儲存資料的容器) 陣列 (Array)、串列(List): 最基本
线性表小结 元素之间的线性关系 顺序表 顺序表:元素相邻存储 单链表:后继指针链接 一维数组 给定下标随机存取
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
第3章 栈和队列(二) 1/.
堆疊 Stack chapter 4 德明科技大學資訊科技系.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第3章 堆栈和队列 堆栈 堆栈应用 队列 队列应用 优先级队列 主要知识点.
第三章 栈与队列 £3.1 栈 £3.3 队列 £3.2 栈的应用举例 £3.1.1 栈的定义 £3.1.2 栈的顺序存储结构
第三章 栈和队列 3.1 栈 3.2 栈的应用举例 3.3 栈与递归的实现 3.4 队列.
第3章 栈和队列(一).
第三章 栈和队列.
数据结构 Data Structure 中南大学 主讲人:王国军,郑瑾 中南大学信息院计科系
資料結構與C++程式設計進階 堆疊與佇列(Stack & Queue) 講師:林業峻 CSIE, NTU 6/ 21, 2010.
第一章 绪论.
栈和队列练习.
Data Structure.
佇列(queue) Lai Ah Fur.
6.3 遍历二叉树和线索二叉树(知识点二) 遍历二叉树 一、问题的提出
第三章 栈和队列.
計數式重複敘述 for 迴圈 P
資料結構 第4章 堆疊.
严蔚敏、吴伟民编著 清华大学出版社 学习网站:
第四章 堆疊與佇列 課前指引 資料結構學科中,堆疊(Stack)與佇列是兩種相當典型的抽象資料型態,也是一種有特定進出規則的線性串列應用,主要特性是限制了資料插入與刪除的位置和方法。本章中將會介紹堆疊與佇列的概念與特性,及在計算機領域的各種相關應用。
樹 2 Michael Tsai 2013/3/26.
4.8 平行线 海南华侨中学 王应寿.
Chapter6 队列(Queues) The Abstract Data Type
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
自我參考結構 (self-reference – 1)
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
top b top a a top 空栈 a 进栈 b 进栈 top top e e e top d d d c c c b b b a a
Linked Lists Prof. Michael Tsai 2013/3/12.
北师大版八年级数学上册 3·1 生活中的平移 澂江四中 李丽波.
Chap2 Stack & Queue.
第四章 栈和队列 栈 ( Stack ) 队列 ( Queue ) 优先队列 (Priority Queue) 小结.
浙江长征职业技术学院—计算机与信息技术系—相方莉制作
第 六 讲 栈和队列(一).
1. 志明打算就客戶服務開發一個語音互動(IVR)系統, 顧客可透過電話鍵盤與系統進行互動。
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
第十二章 位运算.
计算机问题求解 – 论题 基本的数据结构 2018年05月09日.
Data Structure.
Chapter 2 Entity-Relationship Model
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
Q1 以下是10個初生嬰兒,首6個月的體重改變紀錄
13-1 電腦可以協助解決哪些問題 13-2 電腦解題簡介 13-3 電腦解題規劃-演算法 13-4 認識資料結構
Presentation transcript:

第三章 堆疊與佇列的基本應用 3-1 簡介堆疊(Stack) 3-2 迷宮問題研究 3-3 佇列(queue)的介紹 3-4 算術運算式表示法的求值計算 3-5 中序表示法轉換為前序表示法 3-6 前序式與後序式轉換成中序式 written by Wei-ShenLai

堆疊的應用在日常生活中也隨處可以看到,例如大樓電梯、貨架上的貨品等等,都是類似堆疊的資料結構原理。 3-1 簡介堆疊(Stack) 堆疊( S t a c k ) 是一群相同資料型態的組合,所有的動作均在堆疊頂端進行,具「後進先出」( L a s t In , F i r st Out :LIFO) 的特性。在電腦中的應用相當廣泛,例如遞迴呼叫、副程式的呼叫。 堆疊的應用在日常生活中也隨處可以看到,例如大樓電梯、貨架上的貨品等等,都是類似堆疊的資料結構原理。 written by Wei-ShenLai

堆疊是一種抽象型資料結構(Abstract Data Type:ADT),它有下列特性: 3-1-1 堆疊的定義 堆疊是一種抽象型資料結構(Abstract Data Type:ADT),它有下列特性: 僅能從堆疊的頂端存取資料。 資料的存取符合「後進先出」(LIFO,Last In First Out)的原則。 基本運算可以具備五種工作定義( op e r a t i o n ) CREATE:建立一個空堆疊。 PUSH:存放頂端資料, 並傳回新堆疊。 POP:刪除頂端資料, 並傳回新堆疊。 EMPTY:判斷堆疊是否為空堆疊,是則傳回true,不是則傳回false。 FULL:判斷堆疊是否已滿,是則傳回true,不是則傳回false。 written by Wei-ShenLai

3-1-2 堆疊的製作 由於堆疊本身是一種抽象資料型態(ADT),所以可以使用靜態陣列結構或動態鍵結串列(linked list)結構,只要維持堆疊後進先出與從頂端存取資料的兩個基本原則即可。 使用陣列結構結構實作堆疊的優缺點: 優點: 製作與設計的演算法都相當簡單。 缺點: 陣列大小無法事先規劃宣告。往往必須使用最大可能性來考量,這樣會造成記憶體空間的浪費。 使用鏈結串列來製作堆疊的優缺點: 隨時可以動態改變串列長度。 設計時, 演算法較為複雜。 written by Wei-ShenLai

3-1-2 堆疊的製作 利用一個一維陣列S ( 1 : n ) 來表示一個堆疊, S ( 1 ) 可視為堆疊的底部。S ( i ) 為堆疊中第i 個元素,指標t o p 則永遠指向堆疊最頂端的元素。以下我們將堆疊的五種工作定義的演算法表示如下: CREATE:建立堆疊。 CREATE(S) declare S(1:n) top ← 0 END TOP:讀取堆疊頂端元素。 TOP(S) if top=0 then "empty" else S(top) PUSH:存放頂端資料, 並傳回新堆疊。 PUSH(itme,S,top,n) if top ≧ n then call Stack-Full(S) top ← top+1 S(top)← item END/ / 其中i t em 為所要求放入的資料, n 為堆疊最大空間/ / written by Wei-ShenLai

POP:刪除頂端資料, 並傳回新堆疊。 EMPTY:判斷堆疊是否為空堆疊。 FULL:判斷堆疊是否已滿。 POP(item,S) End 3-1-2 堆疊的製作 POP:刪除頂端資料, 並傳回新堆疊。 POP(item,S) if top=0 then call Stack-empty(S) item ← S(top) top ← top-1 End EMPTY:判斷堆疊是否為空堆疊。 Stack-empty(S) if top=0 then true else false FULL:判斷堆疊是否已滿。 Stack-Full(S) if top=n then true written by Wei-ShenLai

Ch03_01.c written by Wei-ShenLai

Ch03_01.c written by Wei-ShenLai

Ch03_01.c written by Wei-ShenLai

Ch03_01.c written by Wei-ShenLai

堆疊在許多方面的應用相當廣泛, 我們可以將它列舉如下: 3-1-2 堆疊的製作 堆疊在許多方面的應用相當廣泛, 我們可以將它列舉如下: 二元樹及森林的走訪運算,例如中序追蹤(inorder)、前序追蹤(preorder)等。 電腦中央處理單元(CPU)的中斷處理(interrupt handling)。 圖形的深度優先( D F S ) 追蹤法。 某些所謂堆疊計算機( s t ack computer ),其指令沒有運算元欄,大部份透過彈出( p o p ) 及壓入( p u s h ) 兩個指令來處理程式。 算術式的轉換和求值, 例如中序法轉換成後序法。 呼叫副程式及返回處理例如要執行呼叫的副程式前,必須先將返回位置( 即下一道指令的位址) 儲存到堆疊中,然後才執行呼叫副程式的動作,等到副程式執行完畢後,再從堆疊中取出返回位址。 編譯錯誤處理(Compiler Syntax Processing)例如當編輯程式發生錯誤或警告訊息時,會將所在的位址推入堆疊中,才顯示出錯誤相關的訊息對照表。 written by Wei-ShenLai

3-1-2 堆疊的製作 【範例:3 . 1 . 1 】 如果主程式呼叫副程式A,A再呼叫副程式B,在B完成後,A再呼叫副程式C,試以堆疊的方法說明呼叫過程。(研究所考試試題) written by Wei-ShenLai

3-1-2 堆疊的製作 【範例:3 . 1 . 2 】 考慮如下所示的鐵路交換網路在圖右邊為編號1,2,3,...,n的火車廂。每一車廂被拖入堆疊,並可以在任何時候將它拖出。如n=3 ,我們可以拖入1 ,拖入2 ,拖入3 然後再將車廂拖出,此時可產生新的車廂順序3,2,1 。請問: (1)n=3時,分別有那幾種排列的方式?那幾種排序方式不可能發生? (2)當n=6時,325641這樣的排列是否可能發生?或者154236?或者154623?又當n=5 時, 32154 這樣的排列是否可能發生? (3)找出一個公式Sn,當有n節車廂時,共有幾種排方式。(高考、研究所試題) written by Wei-ShenLai

出現在結果字串中,數字右方比該數字小的必須由大致小排列 【解答】 3-1-2 堆疊的製作 【解題原理】 出現在結果字串中,數字右方比該數字小的必須由大致小排列 【解答】 (1) 當n=3時,可能的排列方式有五種,分別是123,132,213,231,321。不可能的排列方式有312 (2) 依據堆疊後進先出的原則,所以325641的車廂號碼順序是可以達到。至於154263 與154623 都不可能發生。當n=5 時,可以產生32154 的排列 (154263:因為5右方面以423的順序出現, 154623 :因為5右方面以423的順序出現) (3) written by Wei-ShenLai

遵守三個原則: 一次只能走一格。 遇到牆無法往前走時,則退回一步找找看是否有其他的路可以走。 走過的路不會再走第二次。 3-2 迷宮問題研究 遵守三個原則: 一次只能走一格。 遇到牆無法往前走時,則退回一步找找看是否有其他的路可以走。 走過的路不會再走第二次。 這時我們可以利用二維陣列MAZE[row][col ],並符合以下規則 MAZE[i][j] =1 表示[i][j]處有牆,無法通過 =0 表示[i][j]處無牆,可通行 MAZE[1][1]是入口,MAZE[m][n]是出口 下圖就是一個使用1 0 x 1 2 二維陣列的模擬迷宮表示圖 written by Wei-ShenLai

老鼠目前位置以MAZE[x][y] 表示,那麼我們可以將老鼠可能移動的方向表示如下: 3-2 迷宮問題研究 老鼠目前位置以MAZE[x][y] 表示,那麼我們可以將老鼠可能移動的方向表示如下: 我們可以利用鏈結串列來記 錄走過的位置, 例如: struct list{ int x,y; struct list* next; } 利用堆疊來行走: 並且將走過的位置的陣列元素內容標示為2 ,然後將這個位置p u s h進入堆疊再進行下一次的選擇。如果走到死巷子並且還沒有扺達終點,那麼就必須p o p 出上一個位置並退回去直到回到上一個叉路後再選擇其他的路。如此一直重覆這些動作直到走到出口為止。 written by Wei-ShenLai

3-2 迷宮問題研究 written by Wei-ShenLai

3-2 迷宮問題研究 written by Wei-ShenLai

3-2 迷宮問題研究 written by Wei-ShenLai

3-3 佇列(queue) 的介紹 佇列和堆疊都是一種有序串列,也屬於抽象型資料型態( ADT) ,它所有加入(尾端rear)與刪除(前端front)的動作都發生在不同的兩端,並且符合“First In, First Out”(先進先出) 的特性。 佇列的觀念就好比搭捷運時買票的隊伍,先到的人當然可以優先買票,買完後就從前端離去準備搭捷運,而隊伍的後端又陸續有新的乘客加入排隊。 written by Wei-ShenLai

佇列的建立也可以使用陣列或鏈結串列。現在我們使用一維陣列Q( 1 : n ) 來寫出佇列的五種工作定義與演算法: 3-3-1 佇列的定義 定義: 具有先進先出( F I F O ) 的特性。 擁有兩種基本動作加入與刪除,而且使用f r o n t 與r e a r 兩個指標來分別指向佇列的前端與尾端。 佇列的建立也可以使用陣列或鏈結串列。現在我們使用一維陣列Q( 1 : n ) 來寫出佇列的五種工作定義與演算法: ( 若佇列為Q(0: n - 1 ) 表示此陣列之起始索引位置為0 ,則下列工作定義中的建立空佇列Q ,其中f r on t ← 0 必須修正成f r on t ← -1;r ea r ← 0 必須修正成r e a r ← - 1 。其它四項工作定義的演算法請依同樣邏輯自行修正。) written by Wei-ShenLai

3-3 佇列(queue) 的五種工作定義與演算法 CREATE(Q) declare Q(1:n) front ← 0;rear ← 0 end 將新資料加入Q 的尾端,傳回新佇列。 ADDQ(item,Q,n,rear) if rear=n then call Queue-Full(Q); rear ← rear+1 Q(rear)← item 刪除佇列前端的資料,傳回新佇列。 DeleteQ(item,Q,front,rear) if front=rear then call Queue-Empty(Q); front ← front+1 item ← Q(front) written by Wei-ShenLai

3-3 佇列(queue) 的五種工作定義與演算法 傳回佇列前端的值。 Front(Q) if front=rear then "empty" else Q(front+1); end 若佇列為空集合,傳回真,否則傳回偽。 queue-Empty(Q) if front=rear then true else false written by Wei-ShenLai

Ch03_03.c #include <stdio.h> #include <stdlib.h> #include <conio.h> #define MAX 20 /* 定義佇列的大小*/ void main(){ int front,rear,val,queue[MAX]={0}; char ch;front=rear=-1; while(rear<MAX-1&&ch!='E'){ printf("[I]存入一個數值[G]取出一個數值[E]結束: "); ch=getche(); switch(ch){ case 'I': printf("\n[請輸入數值]: ");scanf("%d",&val); rear++;queue[rear]=val; break; case 'G': if(rear>front){ front++; printf("\n[取出數值為]: [%d]\n",queue[front]); queue[front]=0; } else{ printf("\n[佇列已經空了]\n");exit(0); }break; default: printf("\n");break; } if(rear==MAX-1) printf("[佇列已經滿了]\n"); printf("\n[目前佇列中的資料]:"); if (front>=rear){ printf(" 沒有\n");printf("[佇列已經空了]\n");} while (rear>front){ front++; printf("[%d]\t",queue[front]); printf("\n"); written by Wei-ShenLai

解決想法二:環狀佇列(Circular queue) 經過了以上有關佇列的實作與說明, 我們發現在佇列加入與刪除時,因為佇列需要兩個指標f r o n t , r e a r 來指向它的底部和頂端,當r e a r=n( 佇列容量) 時, 會產生一個小問題。 解決想法一: 缺點:需搬動大量資料。 解決想法二:環狀佇列(Circular queue) written by Wei-ShenLai

3-3-2 環狀佇列(circular queue) 以上所提線性佇列中空間浪費的問題, 其實除了移動資料之外, 利用環狀佇列也可以解決。基本上環狀佇列就是一種環形結構的佇列,它是以一種Q(0:n-1)的一維陣列,同時Q(0)為Q(n-1)的下一個元素。指標front永遠以逆時鐘方向指向佇列中第一個元素的前一個位置,rear則指向佇列目前的最後位置。一開始front和rear均預設為-1,表示為空佇列,也就是說如果front=rear則為空佇列,另外有: rear ← (rear+1) mod n front ← (front+1) mod n 佇列已滿如何判斷: 方法一: rear+1=front 使用n-1個空間 方法二: 利用tag=0表示空佇列 利用tag=1表示滿佇列 使用n個空間 written by Wei-ShenLai

3-3-2 環狀佇列(circular queue) 的五種工作定義與演算法 CREATE(Q)//建立空佇列Q 。 declare Q(0:n-1) front ← 0;rear ← 0; end ADDQ(item,Q,n,rear)//將新資料加入Q 的尾端,傳回新佇列。 rear ←(rear+1) mod n if rear=front then call Queue-Full(Q); Q(rear)← item DeleteQ(item,Q,front,rear)//刪除佇列前端的資料,傳回新佇列。 if front=rear then call Queue-Empty(Q); front ←(front+1) mod n item ← Q(front) written by Wei-ShenLai

3-3-2 環狀佇列(circular queue) 的五種工作定義與演算法 Front(Q)//傳回佇列前端的值。 if front=rear then "empty" else Q(front+1); end queue-Empty(Q)//若佇列為空集合,傳回真,否則傳回偽。 if front=rear then true else false queue-Full(Q)//若佇列已滿,傳回真,否則傳回偽。 if front=(rear+1) mod n then true written by Wei-ShenLai

3-3-3 優先佇列(priority queue) 為一種不必遵守佇列特性- FIFO( 先進先出) 的有序串列,其中的每一個元素都賦予一個優先權(priority),加入元素時可任意加入,但有最高優先權者(Highest Priority Out First: HPOF)則最先輸出。 像一般醫院中的急診室,當然以最嚴重的病患( 如得SARS 的病人) 優先診治,跟進入醫院掛號的順序無關。或者在電腦中C P U 的工作排程,也會使用到優先佇列。好比層級高的使用者, 就比一般使用者擁有較高的權利。 請注意!當各元素以輸入先後次序為優先權時,就是一般的佇列,假如是以輸入先後次序做為最不優先權時, 此優先佇列即為一堆疊。 written by Wei-ShenLai

3-3-4 雙向佇列(double-ended queue:deque) 在雙向佇列中,我們仍然使用2 個指標,分別指向加入及取回端,只是加入及取回時,各指標所扮演的角色不再是固定的加入或取回,而且兩邊的指標都是往佇列中央移動, 其他部份則和一般佇列無異。 written by Wei-ShenLai

利用雙向佇列(deque)循序輸入1,2,3,4,5,6,7,試問是否能夠得到5174236的輸出排列?並說明其過程理由。(高考試題) 【範例:3 . 3 . 3 】 利用雙向佇列(deque)循序輸入1,2,3,4,5,6,7,試問是否能夠得到5174236的輸出排列?並說明其過程理由。(高考試題) 【解答】 於數字串列中尋找循序子串列。 5[1]74[2][3][6] [5]1[7]4236 517[4]23[6] 因為無法以兩個子串列表示完整的串列所以不可能出現 補充問題:可否出現5172346 5[1]7[2][3][4]6 [5]1[7]2346 written by Wei-ShenLai

如在圖形的走訪的先廣後深搜尋法(BFS),就是利用佇列。 3-3-5 佇列的應用 如在圖形的走訪的先廣後深搜尋法(BFS),就是利用佇列。 可用於計算機的模擬(simulation);在模擬過程中,由於各種事件(event)的輸入時間不一定,可以利用佇列來反應真實狀況。 可作為CPU的工作排程(Job Scheduling)。利用佇列來處理,可達到先到先做的要求。 例如「線上同時週邊作業系統」的應用,也就是讓輸出入的資料先在高速磁碟機中完成, 也就是把磁碟當成一個大型的工作緩衝區(buffer),如此可讓輸出入動作快速完成,也縮短了反應的時間( 接下來將磁碟資料輸出到列表機是由系統軟體主動負責) ,這也是應用了佇列的工作原理。 written by Wei-ShenLai

何謂多重堆疊(multi stack)與多重佇列(multiqueue)?試說明定義與目的(研究所考題) 【解答】 3-3-5 佇列的應用 【範例:3.3.6】 何謂多重堆疊(multi stack)與多重佇列(multiqueue)?試說明定義與目的(研究所考題) 【解答】 (1) 我們可以使用一維陣列S(1:n)表示,假設陣列分給m個堆疊使用,令B(i)表示第i個堆疊的底部,T(i)為第i個堆疊的頂端,而且每一個堆疊為空時,T(i)=B(i)且T(i)=B(i)=int[n/m]*(i-1) , 1 ≦ i ≦m 其中多重堆疊加入(push)與刪除(pop)的演算法如下所示: Procedure push(i,x) if T(i)=B(i+1) then call Stack_Full(i) T(i)← T(i)+1 S(T(i))←x end Procedure pop(i,x) if T(i)=B(i) then call Stack_Empty(i) x← S(T(i)) T(i)← T(i)-1 written by Wei-ShenLai

典型算術運算式: 中序法(infix) 前序法(prefix) 後序法(postfix) (6*2+5*9)/3 3-4 算術運算式表示法的求值計算 典型算術運算式: (6*2+5*9)/3 而上述運算式的表示法,我們稱為中序表示法(infix notation),這也是我們一般人所習慣的寫法。 中序法(infix) <運算元1><運算子><運算元2> 例如2+3 、3*5 、8 - 2 等等都是中序表示法。 前序法(prefix) 前序運算式的表示法是把運算子置於兩個運算元的最前面: <運算子><運算元1><運算元2> 例如中序運算式2+3 ,前序運算式的表示法則為+23 ,而2*3+4*5 則為+*23*45 。 後序法(postfix) 後序運算式是把運算子放在兩個運算元的後面: <運算元1><運算元2><運算子> 例如中序運算式2+3 ,後序運算式的表示法為23+ ,而2*3+4*5 的後序表示法為23*45+ 。 written by Wei-ShenLai

由中序表示法來求值, 可依照底下五個步驟: 3-4-1 中序表示法求值 由中序表示法來求值, 可依照底下五個步驟: 建立兩個堆疊,分別存放運算子及運算元。 讀取運算子時, 必須先比較堆疊內的運算子優先權, 若堆疊內運算子的優先權較高, 則先計算堆疊內運算子的值。 計算時, 取出一個運算子及兩個運算元進行運算, 運算結果直接存回運算元堆疊中, 當成一個獨立的運算元。 當運算式處理完畢後,一步一步清除運算子堆疊,直到堆疊空了為止。 取出運算元堆疊中的值就是計算結果。 written by Wei-ShenLai

現在就以上述五個步驟,來求取中序表示法2+3*4+5 的值。 3-4-1 中序表示法求值 現在就以上述五個步驟,來求取中序表示法2+3*4+5 的值。 運算子 運算元 + 2 3 + * 4 (3*4) 5 12+5 2+17 19 written by Wei-ShenLai

3-4-2 前序表示法求值 使用前序表示法求值的好處是不需考慮括號及優先權的問題,所以直接使用一個堆疊來處理運算式即可,不需把運算元及運算子分開處理。我們來實作前序運算式+*23*45 如何使用堆疊來運算的步驟: 前序運算 式堆疊 + * 2 3 * 4 5 運算元 5*4 20 + 3*2 20+6 written by Wei-ShenLai

3-4-3 後序表示法求值 後序運算式具有和前序運算式類似的好處, 它沒有優先權的問題,而且後序運算式可以直接在電腦上進行運算, 而不需先全數放入堆疊後再讀回運算。另外在後序運算式中,它使用迴圈直接讀取運算式,如果遇到運算子就從堆疊中取出運算元進行運算。我們繼續來實作後序表示法23*45*+ 的求值運算: 運算元 2 3 2*3 6 4 5 4*5 20 6+20 26 written by Wei-ShenLai

如何將中序表示法轉換成容易讓電腦進行處理的前序與後序表示法呢? 其實有三種常用的轉換方法。 3-5 中序表示法轉換為前序表示法 如何將中序表示法轉換成容易讓電腦進行處理的前序與後序表示法呢? 其實有三種常用的轉換方法。 二元樹法: 留待第五章樹狀結構 括號法: 括號法就是先用括號把中序運算式的優先順序分出來, 再進行運算子的移動, 最後把括號拿掉就可完成中序轉後序或中序轉前序了。 (1)中序(infix)→前序(prefix) 將中序運算式根據順序完全括號起來。 移動所有運算子來取代所有的左括號,並以最近者為原則 將所有右括號去掉 (2)中序(infix)→後序(postfix) 移動所有運算子來取代所有的右括號,並以最近者為原則 將所有左括號去掉 堆疊法:(P3-53) written by Wei-ShenLai

例如我們以括號把下列中序運算式轉成前序及後序。2*3+4*5 【作法如下】 中序→前序 3-5 中序表示法轉換為前序表示法 例如我們以括號把下列中序運算式轉成前序及後序。2*3+4*5 【作法如下】 中序→前序 中序→後序 written by Wei-ShenLai

【範例:3 . 5 . 1 】 【解答】 請將6+2*9/3+4*2 - 8 用括號法轉成前序法或後序法。 written by Wei-ShenLai

【範例:3 . 5 . 3 】 【解答】 將下列中序算術式轉換為前序與後序算術式。 (1) A/B↑C+D*E-A*C (2) (A+B)*D+E/(F+A*D)+C (3) A ↑ B ↑ C (4) A↑- B+C(高考試題) 【解答】 written by Wei-ShenLai

【解答】 written by Wei-ShenLai

堆疊法 利用堆疊將中序法轉換成前序,其ISP(In Stack Priority)是「堆疊內優先權」的意思,ICP(I n Coming Priority) 是「輸入優先權」的意思。運作步驟如下: (1 ) 中序→前序 由右至左讀進中序運算式的每個字元。 如果輸入為運算元則直接輸出。 ' ) ' 在堆疊中的優先權最小,但在堆疊外卻是優先權最大。 如果遇到' ( ' ,則彈出堆疊內的運算子,直到彈出到一個' ) ' 為止。 如果ISP>ICP 則將堆疊的運算子彈出,否則就加入到堆疊內。 (2 ) 中序→後序 由左至右每次讀入一個字元。 輸入為運算元則直接輸出。 如果ISP>=ICP ,則將堆疊內的運算子直接彈出,否則就加入到堆疊內。 ' ( ' 在堆疊中的優先權最小,不過如果在堆疊外,它的優先權最大。 如果遇到')' ,則直接彈出堆疊內的運算子,一直到彈出一個'(' 為止。 written by Wei-ShenLai

中序→前序 中序→後序 ISP ICP written by Wei-ShenLai

中序→前序 中序→後序 ISP ICP ↑,+,- 7 *,/ 6 +,- 5 <,<=,>,>= 4 not 3 運算子優先權定義方式 中序→前序 中序→後序 ISP ICP ↑,+,- 7 *,/ 6 +,- 5 <,<=,>,>= 4 not 3 and 2 or 1 ) 8 ( written by Wei-ShenLai

知道堆疊法的實作程序後,我們來以堆疊法求中序式A -B*(C+D)/E 的後序法與前序法。 讀入字元 Token 堆疊內容 Stack 輸出 中序→前序 知道堆疊法的實作程序後,我們來以堆疊法求中序式A -B*(C+D)/E 的後序法與前序法。 讀入字元 Token 堆疊內容 Stack 輸出 Output(堆疊行為) 說明 None Empty E 運算元E直接輸出 / 運算子放入堆疊 ) )/ )直接放入堆疊 D DE 運算元D直接輸出 + +)/ ISP<=ICP放入堆疊 C CDE 運算元C直接輸出 ( +CDE (輸出堆疊內容至)為止 * */ B B+CDE 運算元B直接輸出 - /*B+CDE ISP>ICP由堆疊取出 A A/*B+CDE 運算元A直接輸出 - A/*B+CDE 讀入完畢將堆疊內容一一取出 written by Wei-ShenLai

知道堆疊法的實作程序後,我們來以堆疊法求中序式A -B*(C+D)/E 的後序法與前序法。 讀入字元 Token 堆疊內容 Stack 輸出 中序→後序 知道堆疊法的實作程序後,我們來以堆疊法求中序式A -B*(C+D)/E 的後序法與前序法。 讀入字元 Token 堆疊內容 Stack 輸出 Output(佇列行為) 說明 None Empty A 運算元A直接輸出 - 運算子放入堆疊 B AB 運算元B直接輸出 * *- ISP<ICP放入堆疊 ( (*- (直接放入堆疊 C ABC 運算元C直接輸出 + +(*- D ABCD 運算元D直接輸出 ) ABCD+ )輸出堆疊內容至(為止 / /- ABCD+* ISP>=ICP由堆疊取出 E ABCD+*E 運算元E直接輸出 ABCD+*E- 讀入完畢將堆疊內容一一取出 written by Wei-ShenLai

3-6 前序式與後序式轉換成中序式 上節介紹的方法都是中序轉換成前序或後序運算式, 但如何把前序或後序轉換成中序運算式呢?我們一樣可以使用括號法及堆疊法來進行轉換。不過轉換方式略有不同, 請看下列說明: 3-6-1 括號法 3-6-2 堆疊法 written by Wei-ShenLai

前序→ 中序: 依次將每個運算子, 以最近為原則取代後方的右括號,最後再去掉所有左括號。例如:+* 2 3 * 4 5 3-6-1 括號法 以括號法來求得運算式( 前序式與後序式) 的反轉為中序式的作法,若為前序必須以「運算子+ 運算元」的方式括號; 若為後序必須以「運算元+ 運算子」的方式括號。另外還必須遵守以下原則: 前序→ 中序: 依次將每個運算子, 以最近為原則取代後方的右括號,最後再去掉所有左括號。例如:+* 2 3 * 4 5 【作法】 依「運算子+ 運算元」原則括號 或者:-++6/*293*458 written by Wei-ShenLai

後序→ 中序: 依次將每個運算子, 以最近為原則取代後方的右括號,最後再去掉所有左括號。例如:ABC ↑ /DE*+AC*- 3-6-1 括號法 後序→ 中序: 依次將每個運算子, 以最近為原則取代後方的右括號,最後再去掉所有左括號。例如:ABC ↑ /DE*+AC*- 【作法】 依「運算子+ 運算元」原則括號 written by Wei-ShenLai

以堆疊法來求得運算式( 前序式與後序式) 的反轉為中序式的作法必須遵照下列規則: 3-6-2 堆疊法 以堆疊法來求得運算式( 前序式與後序式) 的反轉為中序式的作法必須遵照下列規則: 若要轉換為前序, 由右至左讀進運算式的每個字元; 若是要轉換成後序, 則讀取方向改成由左至右。 辨別讀入字元, 若為運算元則放入堆疊中。 辨別讀入字元, 若為運算子則從堆疊中取出兩個字元, 結合成一個基本的中序運算式( < 運算元><運算子><運算元> ) 後,再把結果放入堆疊。 在轉換過程中,前序和後序的結合方式是不同的,前序是< 運算元2 ><運算子><運算元1>而後序是<運算元1><運算子><運算元2>,如下圖所示: 前序轉中序:<OP2><運算子><OP1> 後序轉中序:<OP1><運算子><OP2> written by Wei-ShenLai

((A/B *C)-D)+(E+F)/(G+H) 【作法】 +-*/ABCD//EF+GH 從右至左讀取字元, 如果為運算元則放入堆疊。 堆疊 H G G+H F E G+H E/F (E+F)/(G+H) D C B A A/B A/B *C (A/B *C)-D ((A/B *C)-D)+(E+F)/(G+H) written by Wei-ShenLai

((A+B)*C)-((D-E)*(F+G)) 【作法】 AB+C*DE-FG+*- 從左至右讀取字元, 如果為運算元則放入堆疊。 堆疊 A B A+B C (A+B)*C D E D-E F G F+G (D-E)*(F+G) ((A+B)*C)-((D-E)*(F+G)) written by Wei-ShenLai