350 likes | 506 Views
Stack. FIFO และ LIFO. F irst I n F irst O ut : FIFO หมายถึงข้อมูลที่ เข้ามา ในลิสต์ ก่อน จะถูก นำออก จากลิสต์เป็น ลำดับแรก ตัวอย่างได้แก่การยืนรอคิวเพื่อซื้อตั๋ว
E N D
FIFO และ LIFO • First In First Out : FIFOหมายถึงข้อมูลที่เข้ามาในลิสต์ก่อน จะถูกนำออกจากลิสต์เป็นลำดับแรก ตัวอย่างได้แก่การยืนรอคิวเพื่อซื้อตั๋ว • Last In First Out : LIFOหมายถึงข้อมูลที่เข้ามาในลิสต์เป็นลำดับสุดท้าย จะถูกนำออกจากลิสต์เป็นอันดับแรก ตัวอย่างได้แก่การนำชั้นของปิ่นโตเข้าและออกจากเถาปิ่นโต
Stack • เป็นโครงสร้างข้อมูลแบบเชิงเส้น ที่มีการใส่ข้อมูลเข้า และนำข้อมูลออกเพียงด้านเดียว ดังนั้น ข้อมูลที่เข้าไปอยู่ใน stack ก่อนจะออกจาก stack หลังข้อมูลที่เข้าไปใน stack ทีหลัง นั่นคือ การ "เข้าทีหลังแต่ออกก่อน" (Last In First Out : LIFO)
การกระทำ(Operation) ที่เกี่ยวข้องกับโครงสร้างข้อมูลแบบ Stack • ปฏิบัติการพื้นฐานของStackได้แก่ push คือการนำข้อมูลเก็บในStack และ pop คือการนำข้อมูลออกจากStack ซึ่งทั้งสองกระบวนการ จะกระทำที่ส่วนบนสุดของStackเสมอ โดยปกติแล้วมักกำหนดให้มีตัวชี้ส่วนบนสุดของStack เรียกว่า topส่วนปฏิบัติการอื่น ๆ เป็นปฏิบัติการที่เกี่ยวเนื่องกับการ push และ pop มีดังนี้ • การสร้างStack (CREATE) • การทดสอบว่า stack ว่างหรือไม่(EMPTY) • การทดสอบว่า stack เต็มหรือไม่(FULL) • การทำให้ stack เป็น stack ว่าง(CLEAR)
การนำข้อมูลเข้าสู่Stack(Push) กระทำที่ส่วนบนของStack (Top) ซึ่งต้องมีการตรวจสอบก่อนว่าStackเต็มหรือไม่ • และการนำข้อมูลออกจากStack (Pop) กระทำที่ส่วนบนของStackเช่นกัน โดยตรวจสอบว่ามีสมาชิกอยู่ในStackหรือไม่ (ตรวจสอบว่าStackว่างเปล่าหรือไม่)
การนำข้อมูลเข้าไปในกองซ้อน (Push) • เป็นการดำเนินการที่นำข้อมูลเข้าไปเก็บไว้ด้านบนสุดของกองซ้อน (Top of the Stack) เรื่อย ๆ จนกว่ากองซ้อนไม่สามารถนำข้อมูลเข้าไปเก็บได้ • จะเรียกว่า กองซ้อนเต็ม (Stack Full)
การนำข้อมูลออกจากกองซ้อน (Pop) • การทำงานจะตรงข้ามกับ Push • จะดึงเอาข้อมูลที่อยู่บนสุดออกมาก่อน แต่ก่อนที่จะดึงจะมีการตรวจสอบว่ากองซ้อนว่างหรือไม่ • ถ้าว่างจะไม่สามารถนำข้อมูลออกได้ แสดงว่ากองซ้อนว่าง (Stack Empty) • ถ้าไม่ว่างจะนำเอาข้อมูลออกแล้วเลื่อนตัวชี้ไปยังตำแหน่งถัดลงไป
ให้ Y เป็นสแตกเก็บค่าตัวเลขได้ไม่เกิน 6 ตัว Push(‘2’),Push(‘5’),Push(‘3’) Pop(),Push(‘9’), Push(‘0’) Push(‘4’) Push(‘6’),Pop()
เริ่มต้นจากการสร้างสแตก Yขึ้นมาทำงานจำได้สแตกว่าง ไม่มีสมาชิกโดยตัวชี้สแตก Top ยังไม่มีค่า Top
2 นำค่า 2 เข้ามาเก็บเป็นตัวแรกโดยใช้Push(‘2’) สแตก Y=[2] ตัวชี้สแตก Top = 2 Top
5 2 นำค่า 5 เข้ามาเก็บเป็นตัวแรกโดยใช้ Push(‘5’) สแตก Y=[5] ตัวชี้สแตก Top = 5 Top
3 5 2 นำค่า 3 เข้ามาเก็บเป็นตัวแรกโดยใช้ Push(‘3’) สแตก Y=[3] ตัวชี้สแตก Top = 3 Top
2 5 ต้องการดึงค่าออกมาโดยใช้Pop() สแตก Y=[2,5,3]ตัวชี้สแตก Top = 3 Top
9 5 2 นำค่า 9 เข้ามาเก็บเป็นตัวแรกโดยใช้ Push(‘9’) สแตก Y=[9] ตัวชี้สแตก Top = 9 Top
0 9 5 2 นำค่า 0 เข้ามาเก็บเป็นตัวแรกโดยใช้ Push(‘0’) สแตก Y=[0] ตัวชี้สแตก Top = 0 Top
4 0 9 5 2 นำค่า 4 เข้ามาเก็บเป็นตัวแรกโดยใช้ Push(‘4’) สแตก Y=[4] ตัวชี้สแตก Top = 4 Top
6 4 0 9 5 2 นำค่า 6 เข้ามาเก็บเป็นตัวแรกโดยใช้ Push(‘6’) สแตก Y=[6] ตัวชี้สแตก Top = 6 Top
Implementation of Stacks • Any list implementation could be used to implement a stack • Arrays (static: the size of stack is given initially) • Linked lists (dynamic: never become full) • We will explore implementations based on array and linked list • Let’s see how to usean array to implement a stack first
Array Implementation • Need to declare an array size ahead of time • มีทางให้ข้อมูลเข้า และ ข้อมูลออก เพียงด้านเดียว • Associated with each stack is TopOfStack • for an empty stack, set TopOfStack to -1 • Push • (1) Increment TopOfStack by 1. • (2) Set Stack[TopOfStack] = X • Pop • (1) Set return value to Stack[TopOfStack] • (2) Decrement TopOfStack by 1 • These operations are performed in very fast constant time
การสร้างกองซ้อนด้วยแถวลำดับการสร้างกองซ้อนด้วยแถวลำดับ • เป็นการเตรียมเนื้อที่ในหน่วยความจำไว้สำหรับเก็บข้อมูล • ตัวอย่างในภาษาซี คือ int Stack[4]; • การนำข้อมูลเข้าและออกจากหน่วยความจำด้วยแถวลำดับ ก็เหมือนกับที่ยกตัวอย่างไปแล้ว Stack
Stack class class Stack { public: Stack(int size = 10); // constructor ~Stack() { delete [] values; } // destructor bool IsEmpty() { return top == -1; } bool IsFull() { return top == maxTop; } double Top(); void Push(const double x); double Pop(); void DisplayStack(); private: int maxTop; // max stack size = size - 1 int top; // current top of stack double* values; // element array };
Stack class • Attributes of Stack • maxTop: the max size of stack • top: the index of the top element of stack • values: point to an array which stores elements of stack • Operations of Stack • IsEmpty: return true if stack is empty, return false otherwise • IsFull: return true if stack is full, return false otherwise • Top: return the element at the top of stack • Push: add an element to the top of stack • Pop: delete the element at the top of stack • DisplayStack: print all the data in the stack
Create Stack • The constructor of Stack • Allocate a stack array of size. By default, size = 10. • When the stack is full, top will have its maximum value, i.e. size – 1. • Initially top is set to -1. It means the stack is empty. Stack::Stack(int size /*= 10*/) { maxTop = size - 1; values = new double[size]; top = -1; } Although the constructor dynamically allocates the stack array, the stack is still static. The size is fixed after the initialization.
Push Stack • void Push(constdouble x); • Push an element onto the stack • If the stack is full, print the error information. • Note top always represents the index of the top element. After pushing an element, increment top. void Stack::Push(constdouble x) { if (IsFull()) cout << "Error: the stack is full." << endl; else values[++top] = x; }
Pop Stack • double Pop() • Pop and return the element at the top of the stack • If the stack is empty, print the error information. (In this case, the return value is useless.) • Don’t forgot to decrement top double Stack::Pop() { if (IsEmpty()) { cout << "Error: the stack is empty." << endl; return -1; } else { return values[top--]; } }
Stack Top • double Top() • Return the top element of the stack • Unlike Pop, this function does not remove the top element double Stack::Top() { if (IsEmpty()) { cout << "Error: the stack is empty." << endl; return -1; } else return values[top]; }
Printing all the elements • void DisplayStack() • Print all the elements void Stack::DisplayStack() { cout << "top -->"; for (int i = top; i >= 0; i--) cout << "\t|\t" << values[i] << "\t|" << endl; cout << "\t|---------------|" << endl; }
Using Stack result int main(void) { Stack stack(5); stack.Push(5.0); stack.Push(6.5); stack.Push(-3.0); stack.Push(-8.0); stack.DisplayStack(); cout << "Top: " << stack.Top() << endl; stack.Pop(); cout << "Top: " << stack.Top() << endl; while (!stack.IsEmpty()) stack.Pop(); stack.DisplayStack(); return 0; }
การประยุกต์ใช้ stack โครงสร้างข้อมูลแบบ stack มีการประยุกต์ใช้มากในการเขียนโปรแกรมของสาขาวิทยาการคอมพิวเตอร์ เช่น • การจัดสรรหน่วยความจำในการประมวลผลโปรแกรม (Function Call) • รวมทั้ง โปรแกรมเรียกใช้ตัวเอง (Recursive) • การตรวจสอบอักขระสมดุล(Balancing Symbol) • การคำนวณนิพจน์คณิตศาสตร์
Function Call • การเรียกใช้ Function หรือ Procedure หรือโปรแกรมย่อยในภาษาที่ไม่มีการ Recursive • เมื่อมีการเรียกใช้ Function ก็จะทำการ Push Function to Stack • และเมื่อมีการ Return หรือจบการทำงานของ Function แล้วจะต้อง Pop Function from Stack
การเรียกใช้โปรแกรมย่อยการเรียกใช้โปรแกรมย่อย • การเรียกโปรแกรมย่อยมีความแตกต่างกับการกระโดดทั่วไป เนื่องจากภายหลังที่โปรแกรมย่อยทำงานเสร็จ หน่วยประมวลผลจะต้องสามารถกระโดดกลับมาทำงานในโปรแกรมหลักต่อไปได้ดังนั้นการเรียกใช้โปรแกรมย่อยนั้นจะต้องมีการเก็บตำแหน่งของคำสั่งที่ทำงานอยู่เดิมด้วย และเมื่อจบโปรแกรมย่อยโปรแกรมจะต้องกระโดดกลับมาทำงานที่เดิม โดยใช้ข้อมูลที่เก็บไว้ ภาพและอัลกอริทึมแสดงตัวอย่างการเรียกใช้โปรแกรมย่อย
PROGRAM MAIN ...... CALL Sub1 PRINT Q .... END MAIN PROCEDURE Sub1 .... CALL Sub2 A:=A+B ... END Sub1 PROCEDURE Sub2 ... END Sub2
Balancing Symbols Example : {x+(y-[a+b])*c-[(d+e)]}/(h-(j-(k-[l-n])))
การตรวจสอบอักขระสมดุล(Balancing Symbol) • ในการตรวจสอบอักขระสมดุลนั้น คอมไพเลอร์ได้นำแนวคิดโครงสร้างข้อมูลแบบ Stack มาประยุกต์ โดยมีวิธีการดังนี้ • 1. ให้อ่านอักขระทีละตัว • - ถ้าอักขระเป็นอักขระเปิด เช่น {,(,[ เป็นต้น ให้PUSH ลง stack • - ถ้าอักขระเป็นอักขระปิด เช่น },),] เป็นต้น ให้ตรวจสอบว่าอักขระบน TOP ของ stack เป็นอักขระเปิดที่คู่กันหรือไม่ • - ถ้าใช่ ให้ POP อักขระนั้นออกจาก stack • - ถ้าไม่ใช่ ให้แสดงผล error • 2.เมื่ออ่านอักขระหมดแล้ว แต่ stack ไม่เป็น stack ว่าง ให้แสดงผล error