1 / 45

บทที่ 4 สแตกและคิว (Stack & Queue)

บทที่ 4 สแตกและคิว (Stack & Queue). FIFO และ LIFO. F irst I n F isrt O ut : FIFO หมายถึงข้อมูลที่ เข้ามา ในลิสต์ ก่อน จะถูก นำออก จากลิสต์เป็น ลำดับแรก ตัวอย่างได้แก่การยืนรอคิวเพื่อซื้อตั๋ว

tallys
Download Presentation

บทที่ 4 สแตกและคิว (Stack & Queue)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. บทที่ 4สแตกและคิว (Stack & Queue)

  2. FIFO และ LIFO • First In Fisrt Out : FIFOหมายถึงข้อมูลที่เข้ามาในลิสต์ก่อน จะถูกนำออกจากลิสต์เป็นลำดับแรก ตัวอย่างได้แก่การยืนรอคิวเพื่อซื้อตั๋ว • Last In First Out : LIFOหมายถึงข้อมูลที่เข้ามาในลิสต์เป็นลำดับสุดท้าย จะถูกนำออกจากลิสต์เป็นอันดับแรก ตัวอย่างได้แก่การนำชั้นของปิ่นโตเข้าและออกจากเถาปิ่นโต

  3. สแตก(stack) • เป็นโครงสร้างข้อมูลแบบเชิงเส้น ที่มีการใส่ข้อมูลเข้า และนำข้อมูลออกเพียงด้านเดียว ดังนั้น ข้อมูลที่เข้าไปอยู่ใน stack ก่อนจะออกจาก stack หลังข้อมูลที่เข้าไปใน stack ทีหลัง นั่นคือ การ "เข้าทีหลังแต่ออกก่อน" (Last In First Out : LIFO)

  4. การกระทำ(Operation) ที่เกี่ยวข้องกับโครงสร้างข้อมูลแบบ Stack • ปฏิบัติการพื้นฐานของสแตกได้แก่ push คือการนำข้อมูลเก็บในสแตก และ pop คือการนำข้อมูลออกจากสแตก ซึ่งทั้งสองกระบวนการ จะกระทำที่ส่วนบนสุดของสแตกเสมอ โดยปกติแล้วมักกำหนดให้มีตัวชี้ส่วนบนสุดของสแตก เรียกว่า topส่วนปฏิบัติการอื่น ๆ เป็นปฏิบัติการที่เกี่ยวเนื่องกับการ push และ pop มีดังนี้ • การสร้างสแตก (CREATE) • การทดสอบว่า stack ว่างหรือไม่(EMPTY) • การทดสอบว่า stack เต็มหรือไม่(FULL) • การทำให้ stack เป็น stack ว่าง(CLEAR)

  5. การนำข้อมูลเข้าสู่สแตก (Push) กระทำที่ส่วนบนของสแตก (Top) ซึ่งต้องมีการตรวจสอบก่อนว่าสแตกเต็มหรือไม่ • และการนำข้อมูลออกจากสแตก (Pop) กระทำที่ส่วนบนของสแตกเช่นกัน โดยตรวจสอบว่ามีสมาชิกอยู่ในสแตกหรือไม่ (ตรวจสอบว่าสแตกว่างเปล่าหรือไม่)

  6. การนำข้อมูลเข้าไปในกองซ้อน (Push) • เป็นการดำเนินการที่นำข้อมูลเข้าไปเก็บไว้ด้านบนสุดของกองซ้อน (Top of the Stack) เรื่อย ๆ จนกว่ากองซ้อนไม่สามารถนำข้อมูลเข้าไปเก็บได้ • จะเรียกว่า กองซ้อนเต็ม (Stack Full)

  7. ตัวอย่างการนำข้อมูลเข้าตัวอย่างการนำข้อมูลเข้า 90 Stack Full 1. Top = 0 2. Top = Top + 1 4 10 3. Stack[Top] = 40 15 60 3 2 1 Top 0 Stack

  8. การนำข้อมูลออกจากกองซ้อน (Pop) • การทำงานจะตรงข้ามกับ Push • จะดึงเอาข้อมูลที่อยู่บนสุดออกมาก่อน แต่ก่อนที่จะดึงจะมีการตรวจสอบว่ากองซ้อนว่างหรือไม่ • ถ้าว่างจะไม่สามารถนำข้อมูลออกได้ แสดงว่ากองซ้อนว่าง (Stack Empty) • ถ้าไม่ว่างจะนำเอาข้อมูลออกแล้วเลื่อนตัวชี้ไปยังตำแหน่งถัดลงไป

  9. Temp 4 3 2 1 0 Stack ตัวอย่างการนำข้อมูลออก 1. Temp = Stack[Top] Top 60 2. Top = Top - 1 40 Stack Empty 15 10

  10. การสร้าง stack ด้วย Array • หมายถึง การแทนที่ข้อมูลของ stack ด้วย arrayซึ่ง เป็นการจัดสรรเนื้อที่หน่วยความจำแบบ staticนั่นคือ • มีการกำหนดขนาดของ stack ล่วงหน้าว่ามีขนาดเท่าใด และจะมีการจัดสรรเนื้อที่หน่วยความจำให้เลย

  11. การแทนที่โครงสร้างข้อมูลแบบกองซ้อนด้วยแถวลำดับการแทนที่โครงสร้างข้อมูลแบบกองซ้อนด้วยแถวลำดับ • แบบลำดับจะต้องมีการจองพื้นที่หน่วยความจำไว้ล่วงหน้า ว่าจะมีขนาดเท่าใด • โดยแถวลำดับนี้จะปิดปลายด้านหนึ่งไว้ เพื่อให้ข้อมูลเข้า-ออกทางเดียว • ปฏิบัติการมี 4 ขั้นตอนคือ • การสร้าง • การ Push • การ Pop • การ แสดง

  12. การสร้างกองซ้อนด้วยแถวลำดับการสร้างกองซ้อนด้วยแถวลำดับ • เป็นการเตรียมเนื้อที่ในหน่วยความจำไว้สำหรับเก็บข้อมูล • ตัวอย่างในภาษาซี คือ int Stack[4]; • การนำข้อมูลเข้าและออกจากหน่วยความจำด้วยแถวลำดับ ก็เหมือนกับที่ยกตัวอย่างไปแล้ว Stack

  13. การแสดงข้อมูลที่อยู่ในกองซ้อนด้วยแถวลำดับการแสดงข้อมูลที่อยู่ในกองซ้อนด้วยแถวลำดับ • จะเป็นการดึงข้อมูลตั้งแต่ตำแหน่งแรกจนถึงตำแหน่งที่ Topชี้อยู่ออกมาแสดง • หรือจะกลับกันคือ นำข้อมูลจากตำแหน่ง Top ชี้อยู่จนถึงตำแหน่งที่ 0 ออกมาแสดง

  14. แสดงข้อมูล 4 3 2 1 0 Stack Top I 60 60 40 40 15 15 10 10

  15. การสร้าง stack ด้วย Link List • หมายถึง การแทนที่ข้อมูลของ stack ด้วย Link list ซึ่งเป็นการจัดสรรเนื้อที่หน่วยความจำแบบ Dynamic นั่นคือ หน่วยความจำจะถูกจัดสรรเมื่อมีการของใช้จริงๆ ระหว่างการประมวลผลโปรแกรมผ่านตัวแปรชนิด Pointer

  16. การแทนที่โครงสร้างข้อมูลกองซ้อนด้วยรายการโยงการแทนที่โครงสร้างข้อมูลกองซ้อนด้วยรายการโยง • เป็นการแทนที่ที่มีความยืดหยุ่นมาก • เนื่องจากไม่ต้องกำหนดหรือจองหน่วยความจำล่วงหน้า • ข้อมูลที่เก็บในกองซ้อนมีจำนวนเท่าใดก็ได้ การปฏิบัติการมี 4 ขั้นตอนคือ การสร้าง, การ Push, การ Pop และการแสดง

  17. data การสร้างกองซ้อนด้วยรายการโยง • ตัวอย่างกรณีที่เป็น รายการโยงแบบเดี่ยว การสร้างจะเป็นดังนี้ typedef struct node { int data; struct node *Next; } node; node *Top; int info; node Next

  18. การนำข้อมูลเข้าไปในกองซ้อนแบบรายการโยงการนำข้อมูลเข้าไปในกองซ้อนแบบรายการโยง P 1. Top = Null 2. New(P) Top 80 ^ 3. Data(p) = 80 4. Next(p) = Null 5. Top = p

  19. การนำข้อมูลเข้าไปในกองซ้อนแบบรายการโยงการนำข้อมูลเข้าไปในกองซ้อนแบบรายการโยง • เพิ่มข้อมูล 90 เข้าไปในรายการโยง P Top 1. New(P) Top 90 80 ^ 2. Data(P) = 90 3. Next(P) = Top 4. Top = p

  20. การนำข้อมูลเข้าไปในกองซ้อนแบบรายการโยงการนำข้อมูลเข้าไปในกองซ้อนแบบรายการโยง P Top Top 120 90 80 ^ 1. New(P) 3. Next(P) = Top 2. Data(P) = 120 4. Top = p

  21. 120 การนำข้อมูลออกจากกองซ้อนด้วยรายการโยง Temp Top Top 90 80 ^ 1. Temp=Top 2. Top = Next(Top)

  22. 90 การนำข้อมูลออกจากกองซ้อนด้วยรายการโยง Temp Top Top ^ 80 1. Temp=Top 2. Top = Next(Top)

  23. 80 การนำข้อมูลออกจากกองซ้อนด้วยรายการโยง Temp Top = NULL Top 1. Temp=Top 2. Top = Next(Top)

  24. การนำข้อมูลออกจากกองซ้อนด้วยรายการโยงการนำข้อมูลออกจากกองซ้อนด้วยรายการโยง Stack Empty Top = NULL 1. Temp=Top

  25. การแสดงข้อมูลที่อยู่ในกองซ้อนด้วยรายการโยงการแสดงข้อมูลที่อยู่ในกองซ้อนด้วยรายการโยง P P P 120 Top 120 90 80 ^ 90 80

  26. การประยุกต์ใช้ stack • โครงสร้างข้อมูลแบบ stack มีการประยุกต์ใช้มากในการเขียนโปรแกรมของสาขาวิทยาการคอมพิวเตอร์ เช่น การจัดสรรหน่วยความจำในการประมวลผลโปรแกรม การตรวจสอบอักขระสมดุล(Balancing Symbol) และการคำนวณนิพจน์คณิตศาสตร์

  27. การเรียกใช้โปรแกรมย่อยการเรียกใช้โปรแกรมย่อย • การเรียกโปรแกรมย่อยมีความแตกต่างกับการกระโดดทั่วไป เนื่องจากภายหลังที่โปรแกรมย่อยทำงานเสร็จ หน่วยประมวลผลจะต้องสามารถกระโดดกลับมาทำงานในโปรแกรมหลักต่อไปได้ดังนั้นการเรียกใช้โปรแกรมย่อยนั้นจะต้องมีการเก็บตำแหน่งของคำสั่งที่ทำงานอยู่เดิมด้วย และเมื่อจบโปรแกรมย่อยโปรแกรมจะต้องกระโดดกลับมาทำงานที่เดิม โดยใช้ข้อมูลที่เก็บไว้ ภาพและอัลกอริทึมแสดงตัวอย่างการเรียกใช้โปรแกรมย่อย

  28. PROGRAM MAIN ...... CALL Sub1 PRINT Q .... END MAIN PROCEDURE Sub1 .... CALL Sub2 A:=A+B ... END Sub1 PROCEDURE Sub2 ... END Sub2

  29. การประยุกต์ใช้โครงสร้างข้อมูลแบบกองซ้อนการประยุกต์ใช้โครงสร้างข้อมูลแบบกองซ้อน • การเรียกใช้โปรแกรมย่อยอื่น • โปรแกรมย่อยที่เรียกใช้ตัวเอง • Factorial • การคำนวณนิพจน์ทางคณิตศาสตร์

  30. B B1 ----- Call B1 ----- Return ----- ----- Return 1500 ----- Call B ----- Call C สิ้นสุดโปรแกรม ----- ----- Return 1000 C การเรียกใช้โปรแกรมอื่น 1500 1000 Stack

  31. Factorial • สัญลักษณ์แฟกตอเรียลเขียนเป็น n! 0! = 1 1! = 1 2! = 2 x 1 3! = 3 x 2 x 1 n! = n x (n-1) x (n-2) x …x 2 x 1

  32. Push 3! 4 3! = 3 * 2! 2! = 2 * 1! 1 3 1! = 1 * 0! 2 2 Pop 0! = 1 1 3 1! = 1 * 1 Top 0 Stack 2! = 2 * 1 3! = 3 * 2

  33. การตรวจสอบอักขระสมดุล(Balancing Symbol) • ในการตรวจสอบอักขระสมดุลนั้น คอมไพเลอร์ได้นำแนวคิดโครงสร้างข้อมูลแบบ Stack มาประยุกต์ โดยมีวิธีการดังนี้ • 1. ให้อ่านอักขระทีละตัว • - ถ้าอักขระเป็นอักขระเปิด เช่น {,(,[ เป็นต้น ให้PUSH ลง stack • - ถ้าอักขระเป็นอักขระปิด เช่น },),] เป็นต้น ให้ตรวจสอบว่าอักขระบน TOP ของ stack เป็นอักขระเปิดที่คู่กันหรือไม่ • - ถ้าใช่ ให้ POP อักขระนั้นออกจาก stack • - ถ้าไม่ใช่ ให้แสดงผล error • 2.เมื่ออ่านอักขระหมดแล้ว แต่ stack ไม่เป็น stack ว่าง ให้แสดงผล error

  34. โพลิช โนเตชัน(Polish Notation) • เป็นวิธีการจัดรูปแบบของสมการใหม่ โดยการย้ายตำแหน่งของเครื่องหมายและตัวดำเนินการ เช่น 2*3 เขียนเป็น *23เป็นต้น โดยมีรูปแบบการเขียนสมการ ดังนี้ • Prefix: การเขียนสมการโดยให้เครื่องหมายอยู่หน้าตัวดำเนินการ • เช่น * + 5 3 2 • Infix : การเขียนสมการโดยให้เครื่องหมายอยู่ระหว่างตัวดำเนินการ • เช่น (5+3)*2 • Postfix : การเขียนสมการโดยให้เครื่องหมายอยู่หลังตัวดำเนินการ • เช่น 5 3 + 2 *

  35. Algorithm การคำนวณแบบ Postfix • ให้อ่านข้อมูลจากซ้ายไปขวาทีละตัว • ถ้าพบตัวถูกดำเนินการ(ตัวเลข) ให้ push stack • ถ้าพบตัวดำเนินการ(เครื่องหมาย) ให้ pop item บนสุดของ stack 2 ตัว แล้วทำการคำนวณตามเครื่องหมายที่พบ แล้วนำผลลัพธ์ที่ได้ push stack • ทำซ้ำจนกระทั่งหมดข้อมูล

  36. Algorithm การคำนวณแบบ Postfix

  37. วิธีการเปลี่ยน Infix เป็น Postfix • Algorithm การเปลี่ยน Infix เป็น Postfix • ให้ EXP เป็นสมการคณิตศาสตร์ที่เป็น Infix และ Stack เป็น stack ใด ๆ NEXP เป็นสมการที่เป็น Postfix • 1. ใส่ “(“ เข้าไปใน Stack • 2. อ่าน EXP จากซ้ายไปขวา • 2.1 ถ้าพบตัวถูกดำเนินการ(ตัวเลข) ให้ใส่เข้าไปใน NEXP • 2.2 ถ้าพบ “(“ ให้ push ใส่ stack

  38. วิธีการเปลี่ยน Infix เป็น Postfix • 2.3 ถ้าพบตัวดำเนินการ(เครื่องหมาย) ให้ทำดังนี้ • - ให้ pop ตัวดำเนินการ ทุกตัวที่มีลำดับความสำคัญกว่าตัวดำเนินการที่พบใน 2.3 ออกมาใส่ใน NEXP ให้หมด • - นำตัวดำเนินการที่พบใน 2.3 push เข้าใน stack แทนที่ • 2.4 ถ้าพบ “)” ให้ทำดังนี้ • - ให้ push ตัวดำเนินการ ทุกตัวมาใส่ไว้ใน NEXP ให้หมดจนพบ “(“ • - push “(“ ทิ้ง • 3. จบการทำงาน

  39. ความสำคัญของตัวดำเนินการความสำคัญของตัวดำเนินการ

  40. A + B

  41. A + B * C

  42. (A + B) * C

  43. ((10/2-2)*2+2)

  44. 8*(4+3)-9/6

  45. ลองทำดู • จงเปลี่ยนนิพจน์อินฟิกซ์ ต่อไปนี้ให้เป็นโพสฟิกซ์ • 1. ((A+B)*C)-D • 2. A*C/D • 3. 10+15*20/6 • 4. 5*4+(8/2) • 5. 10/(2+3)+(5+6)*9 • 6. A*(B-C/D)+E

More Related