สแตกและคิว (stack & queue)
TRANSCRIPT
Week 7 สแตกและคิว (Stack & Queue)
FIFO และ LIFO
First In Fisrt Out : FIFO หมายถึงข้อมูลที่เข ้ามาในลิสต์กอ่น จะถูกน ำาออกจากลสิต์เป็นล ำาดบัแรก เช่น การยืนรอคิวเพื่อซื้อตั๋ว
Last In First Out : LIFO หมายถงึข้อมูลที่เข ้ามาในลสิต์เป็นล ำาด ับส ุดท ้าย จะถกูน ำาออกจากลสิต์เป็นอ ันด ับแรก เช่น การนำาชัน้ของปิ่นโตเข้าและออกจากเถาปิ่นโต
สแตก(stack)เป็นโครงสร้างข้อมูลแบบเชิงเส้น ท ี่ม ี
การใส ่ข ้อมลูเข ้า และนำาข ้อม ูลออกเพียงด ้านเด ียว ดังนั้น ขอ้มลูที่เข้าไปอยูใ่น stack ก่อนจะออกจาก stack หลังขอ้มูลที่เขา้ไปใน stack ทีหลัง นั่นคอื การ "เข ้าท ีหล ังแต ่ออกก่อน" (Last In First Out : LIFO)
การกระทำา(Operation) ที่เก ี่ยวข ้อง กับโครงสร ้างข ้อมลูแบบ Stack
ปฏิบัติการพื้นฐานของสแตกได้แก ่push คือการนำาข ้อม ูลเกบ็ในสแตก และ pop คือการนำาข ้อม ูลออกจากสแตก ซึ่งทั้งสองกระบวนการ จะกระทำาที่ส่วนบนสุดของสแตกเสมอ โดยปกติแล้วมักกำาหนดให้มีต ัวช ี้
ส่วนบนสุดของสแตก เร ียกว ่า top ส่วนปฏิบัติการอื่น ๆ เป็นปฏิบัติการที่เกี่ยวเน่ืองกบัการ push และ pop มีดังน้ี
การ สร ้างสแตก (CREATE)การทดสอบว่า stack ว ่างหร ือไม ่(EMPTY)การทดสอบว่า stack เต ็มหร ือไม ่(FULL)การ ทำาให ้ stack เป ็น stack ว ่าง(CLEAR)
การนำาข ้อม ูลเข ้าส ู่สแตก (Push) กระทำาที่ส่วนบนของสแตก (Top) ซึ่งต ้องม ีการตรวจสอบกอ่นว ่าสแตกเต ็มหร ือไม ่
และการนำาข้อมูล ออกจากสแตก (Pop) กระทำาที่ส่วนบนของสแตกเช่นกัน โดยตรวจสอบว่ามีสมาชิกอยู่ในสแตกหรือไม่ (ตรวจสอบว ่าสแตกว ่างเปลา่หร ือไม ่)
การนำาข้อมูลเข้าไปในกองซ้อน (Push)เป็นการดำาเนินการที่นำาข้อมูลเข้าไปเก็บ
ไว้ด้านบนสุดของกองซ้อน (Top of the Stack) เรื่อย ๆ จนกว่ากองซ้อนไม่สามารถนำาขอ้มูลเข้าไปเก็บได้
จะเรียกว่า กองซ้อนเต็ม (Stack Full)
ตวัอย่างการนำาข้อมูลเข้า
0
1
2
3
4
Top
90
1. Top = 0
2. Top = Top + 1
3. Stack[Top] = 10154060
Stack
Stack Full
การนำาข้อมูลออกจากกองซ้อน (Pop) การทำางานจะตรงข้ามก ับ Pushจะดึงเอาข้อมูลที่อยู่บนสุดออกมาก่อน แต่กอ่นที่จะดึงจะ
มีการตรวจสอบว่ากองซ้อนว่างหรือไม่ ถ้าว ่างจะไมส่ามารถนำาข ้อม ูลออกได้
แสดงว่ากองซ้อนว่าง (Stack Empty)ถ้าไม่ว่างจะนำาเอาข้อมูลออกแล้วเล ื่อนต ัว
ช ีไ้ปยงัต ำาแหนง่ถ ัดลงไป
ตวัอย่างการนำาข้อมูลออกTop
2. Top = Top - 1
1. Temp = Stack[Top]
0
1
2
3
4
Stack
Stack Empty
Temp
10
15
40
60
การสร ้าง stack ด้วย Arrayหมายถึง การแทนที่ข ้อมลูของstack ด้วย array ซึ่ง เป็นการจ ัดสรร
เน ื้อท ี่หน ่วยความจำาแบบ static นั่นคอื
มีการก ำาหนดขนาดของ stack ล่วงหน้าว่ามีขนาดเท่าใด และจะมีการจัดสรรเนื้อที่หน่วยความจำาให้เลย
การแทนทีโ่ครงสร้างข้อมูลแบบกองซ้อนด้วยแถวลำาดับ
แบบลำาดับจะต้องมีการจองพื้นที่หน่วยความจำาไว้ล่วงหน้า ว่าจะมีขนาดเท่าใด
โดยแถวล ำาด ับน ี้จะป ิดปลายดา้นหนึ่งไว ้ เพ ื่อให ้ข ้อม ูลเข ้า -ออกทางเด ียว
ปฏิบัติการมี 4 ข้ันตอนคือการสร้างการ Pushการ Popการ แสดง
การสร้างกองซ้อนด้วยแถวลำาดับเป็นการเตรียมเน้ือที่ในหน่วยความจำาไว้สำาหรับเก็บ
ข้อมูลตัวอย่างในภาษาซี คือ
int Stack[4];
การนำาข้อมูลเข้าและออกจากหน่วยความจำาด้วยแถวลำาดับ ก็เหมือนกับที่ยกตัวอย่างไปแล้ว
Stack
การแสดงข้อมูลทีอ่ยู่ในกองซ้อนด้วยแถวลำาดับจะเป็นการดึงข้อมูลตั้งแต่ตำาแหน่งแรกจนถึงตำาแหน่งที่
Top ชี้อยู่ออกมาแสดงหรือจะกลบักันคือ นำาข้อมูลจากตำาแหน่ง Top ชี้อยู่จนถึง
ตำาแหน่งที่ 0 ออกมาแสดง
I
0
1
2
3
4
Stack
แสดงข้อมูล
10
15
40
60Top
60
40
15
10
การสร ้าง stack ด้วย Link List หมายถึง การแทนที่ข้อมูลของ stack
ด้วย Link list ซึ่งเป็นการจัดสรรเนื้อที่หน่วยความจำาแบบ Dynamic นั่นคอื หน่วยความจำาจะถูกจัดสรรเมื่อมีการของใช้จริงๆ ระหว่างการประมวลผล
โปรแกรมผ่านตัวแปรชนิด Pointer
การแทนทีโ่ครงสร้างข้อมูลกองซ้อนด้วยรายการโยงเป็นการแทนที่ท ี่ม ีความย ืดหย ุ่นมาก เน่ืองจากไม่ต ้องก ำาหนดหรือจองหน่วยความจ ำา
ลว่งหน้าข้อมูลที่เก็บในกองซ้อนมีจำานวนเท่าใดก็ได้ การปฏิบัติ
การมี 4 ข้ันตอนคือ การสร้าง, การ Push, การ Pop และการแสดง
การสร้างกองซ้อนด้วยรายการโยงตัวอย่างกรณีที่เป็น
รายการโยงแบบเดีย่ว การสร้างจะเป็นดังน้ี
typedef struct node
{ int data;
struct node *Next;
} node;
node *Top;
int info;
data
node
Next
การนำาข้อมูลเข้าไปในกองซ้อนแบบรายการโยง
80 ^
P
Top
1. Top = Null2. New(P)3. Data(p) = 804. Next(p) = Null5. Top = p
การนำาข้อมูลเข้าไปในกองซ้อนแบบรายการโยง
เพิ่มข้อมูล 90 เข้าไปในรายการโยง
80 ^
Top
1. New(P)2. Data(P) = 903. Next(P) = Top4. Top = p
P
90Top
การนำาข้อมูลเข้าไปในกองซ้อนแบบรายการโยง
80 ^
Top
1. New(P)2. Data(P) = 120
3. Next(P) = Top
4. Top = p
P
120Top 90
การนำาข้อมูลออกจากกองซ้อนด้วยรายการโยง
80 ^
TopTemp
120Top 90
1. Temp=Top 2. Top = Next(Top)
การนำาข้อมูลออกจากกองซ้อนด้วยรายการโยง
TopTemp
90Top 80
1. Temp=Top 2. Top = Next(Top)
^
การนำาข้อมูลออกจากกองซ้อนด้วยรายการโยง
Top = NULLTemp
80Top
1. Temp=Top 2. Top = Next(Top)
การนำาข้อมูลออกจากกองซ้อนด้วยรายการโยง
Top = NULL
1. Temp=Top
Stack Empty
การแสดงข้อมูลทีอ่ยู่ในกองซ้อนด้วยรายการโยง
80 ^
P
120Top 90
P P
120 90 80
การประย ุกต ์ใช ้ stack โครงสร้างข้อมูลแบบ stack มีการประยุกต์ใช้มากใน
การเขียนโปรแกรมของสาขาวิทยาการคอมพิวเตอร์ เช่น การจัดสรรหน่วยความจำาในการประมวลผลโปรแกรม การตรวจสอบอักขระสมดุล(Balancing Symbol) และการคำานวณนิพจน์คณิตศาสตร์
การเร ียกใช้โปรแกรมย่อย
การเรียกโปรแกรมย่อยมีความแตกต่างกับการกระโดดทั่วไป เน่ืองจากภายหลงัที่โปรแกรมย่อยทำางานเสร็จ หน่วยประมวลผลจะต้องสามารถกระโดดกลับมาทำางานในโปรแกรมหลกัต่อไปได้ ด ังน ั้นการเร ียกใช้โปรแกรมย่อยนั้นจะต ้องม ีการเก ็บต ำาแหน่งของค ำาส ั่งท ี่ท ำางานอยู่เดิมด้วย และเม ื่อจบโปรแกรมย่อยโปรแกรมจะต้องกระโดดกลับมาทำางานทีเ่ด ิม โดยใชข้้อมูลที่เก็บไว้ ภาพและอัลกอริทึมแสดงตัวอย่างการเรียกใชโ้ปรแกรมย่อย
PROGRAM MAIN......CALL Sub1PRINT Q....END MAINPROCEDURE Sub1....CALL Sub2A:=A+B...END Sub1PROCEDURE Sub2...END Sub2
การประยุกตใ์ช้โครงสร้างข้อมูลแบบกองซ้อนการเรียกใช้โปรแกรมย่อยอื่นโปรแกรมย่อยที่เรียกใช้ตัวเอง
Factorialการคำานวณนิพจน์ทางคณิตศาสตร์
การเรียกใช้โปรแกรมอื่น
Stack
-----Call B-----
Call Cสิ้นสุดโปรแกรม
-----Call B1
-----Return
----------
Return
----------
Return1000
1500
B B1
C
1000
1500
Factorialสัญลักษณ์แฟกตอเรียลเขียนเป็น n!
0! = 11! = 12! = 2 x 13! = 3 x 2 x 1n! = n x (n-1) x (n-2) x …x 2 x 1
3!
0
1
2
3
4
Top3
2
1
Stack
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0!
0! = 1
Push
Pop
1! = 1 * 1
2! = 2 * 1
3! = 3 * 2
การตรวจสอบอักขระสมดุล(Balancing Symbol)
ในการตรวจสอบอักขระสมดุลน ัน้ คอมไพเลอร ์ ได้น ำาแนวคิดโครงสร ้างข ้อมลูแบบ Stack มา
ประยกุต ์ โดยมวี ิธกีารดงัน ี้1. ใหอ้ ่านอักขระทลีะต ัว - ถา้อ ักขระเป ็นอ ักขระเป ิด เช ่น {,(,[ เป ็นต ้น
ให้ PUSH ลง stack - ถา้อ ักขระเป ็นอ ักขระปิด เช ่น },),] เป ็นต ้น
ให้ตรวจสอบว่าอ ักขระ บน TOP ของ stack เป ็นอ ักขระเป ิดท ีค่ ู่ก ันหร ือไม ่
- ถา้ใช่ ให ้ POP อักขระนัน้ออกจาก stack - ถา้ไมใ่ช ่ ใหแ้สดงผล error2. เม ือ่อ ่านอ ักขระหมดแล้ว แต่ stack ไมเ่ป ็น
stack ว ่าง ใหแ้สดงผล error
โพลิช โนเตชัน(Polish Notation)
เป็นวิธีการจัดรูปแบบของสมการใหม่ โดยการย ้าย ตำาแหน่งของเคร ื่องหมายและตัวด ำาเน ินการ เชน่ 2*3
เข ียนเป ็น *23 เป็นต้น โดยมีรูปแบบการเขียนสมการ ดังน้ีPrefix : การเขียนสมการโดยให้เครื่องหมายอยู่หน้าตัว
ดำาเนินการ เช่น * + 5 3 2Infix : การเขียนสมการโดยให้เครื่องหมายอยู่ระหว่างตัว
ดำาเนินการ เช่น (5+3)*2Postfix : การเขียนสมการโดยให้เครื่องหมายอยู่หลังตัว
ดำาเนินการ เช่น 5 3 + 2 *
Algorithm การคำานวณแบบ Postfix
ให้อ่านข้อมูลจากซ้ายไปขวาทีละตัวถา้พบตัวถูกดำาเนินการ(ตัวเลข) ให้ push stackถา้พบตัวด ำาเน ินการ(เคร ื่องหมาย) ให้ pop item
บนสุดของ stack 2 ตัว แล้วทำาการคำานวณตามเครื่องหมายที่พบ แล้วนำาผลลัพธท์ี่ได้ push stack
ทำาซ ำ้าจนกระทั่งหมดข้อมลู
Algorithm การคำานวณแบบ Postf ix
ว ิธ ีการเปล ี่ยน Infix เป ็น PostfixAlgorithm การเปล ีย่น Infix เป ็น Postfix ให้ EXP เป็นสมการคณิตศาสตร์ที่เป็น Infix และ
Stack เป็น stack ใด ๆ NEXP เป็นสมการที่เป็น Postfix
1. ใส่ “ (“ เข้าไปใน Stack2. อ่าน EXP จากซ้ายไปขวา 2.1 ถ้าพบตัวถกูดำาเนินการ(ตัวเลข) ให้ใส่เข้าไป
ใน NEXP 2.2 ถ้าพบ “ (“ ให้ push ใส่ stack
ว ิธ ีการเปล ี่ยน Infix เป ็น Postfix2.3 ถ้าพบตัวดำาเนินการ(เครื่องหมาย) ให้ทำาดังน้ี - ให้ pop ตัวดำาเนินการ ทุกตัวที่มีลำาดับความสำาคัญ
กว่าตัวดำาเนินการที่พบใน 2.3 ออกมาใส่ใน NEXP ให้หมด - นำาตัวดำาเนินการที่พบใน 2.3 push เข้าใน stack
แทนที่2.4 ถ้าพบ “ )” ให้ทำาดังน้ี - ให้ push ตัวดำาเนินการ ทุกตัวมาใส่ไว้ใน NEXP ให้
หมดจนพบ “ (“ - push “(“ ทิ้ง3. จบการทำางาน
ความสำาคญัของตวัดำาเนนิการ
เคร ื่องหมาย ความสำาคญัเม ือ่อย ู่ในStack
ความสำาคญัเม ือ่อย ูท่ ี่อ ินพ ุต
** (ยกกำาลัง) 3 4
* , / 2 2
+ , - 1 1
( 0 3
A + B
เครื่องหมาย
Stack นพิจน์ Postfix
A+B
ว่าง++
AAABAB+
A + B * C
เครื่องหมาย Stack นพิจน์ Postfix
A+B*C
ว่าง+++ , *+ , *
AAABABABCABC*+
(A + B) * C
เครื่องหมาย Stack นพิจน์ Postfix
(A+B)*C
(((+(+ว่าง * *
ว่างAAABAB+AB+AB+CAB+C*
((10/2-2)*2+2)
8*(4+3)-9/6เครื่องหมาย Stack นพิจน์ Postfix
8*(4+3)-9 /6ว่าง
ว่าง**(*(*(+*(+*--- /- /
8888 48 48 4 38 4 3 +8 4 3 + *8 4 3 + * 98 4 3 + * 98 4 3 + * 9 68 4 3 + * 9 6 / -
ลองทำาด ูจงเปลีย่นนิพจน์อินฟิกซ์ ต่อไปน้ีให้เป็นโพสฟิกซ์1. ((A+B)*C)-D2. A*C/D3. 10+15*20/64. 5*4+(8/2)5. 10/(2+3)+(5+6)*96. A*(B-C/D)+E