การสร้างStack

advertisement
First In First Out : FIFO หมายถึงข้อมูลทีเ่ ข้ามาในลิสต์ก่อน จะ
ถูกนาออกจากลิสต์เป็ นลาดับแรก ตัวอย่างได้แก่การยืนรอคิวเพือ่ ซือ้ ตั ๋ว

Last In First Out : LIFO หมายถึงข้อมูลทีเ่ ข้ามาในลิสต์เป็ น
ลาดับสุดท้าย จะถูกนาออกจากลิสต์เป็ นอันดับแรก ตัวอย่างได้แก่การนาชัน้ ของ
ปิ่นโตเข้าและออกจากเถาปิ่นโต

 เป็ นโครงสร้างข้อมูลแบบเชิงเส้น ที่มีการใส่ข้อมูลเข้า และ
นาข้อมูลออกเพียงด้านเดียว ดังนัน้ ข้อมูลทีเ่ ข้าไปอยูใ่ น
stack ก่อนจะออกจาก stack หลังข้อมูลทีเ่ ข้าไปใน stack ทีหลัง
นันคื
่ อ การ "เข้าทีหลังแต่ออกก่อน" (Last In First Out :
LIFO)
 ปฏิบตั กิ ารพืน
้ ฐานของ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ว่างเปล่าหรือไม่)
 เป็ นการดาเนินการทีน
่ าข้อมูลเข้าไปเก็บไว้ดา้ นบนสุดของกอง
ซ้อน (Top of the Stack) เรือ่ ย ๆ จนกว่ากองซ้อนไม่สามารถนา
ข้อมูลเข้าไปเก็บได้
 จะเรียกว่า กองซ้อนเต็ม (Stack Full)
 การทางานจะตรงข้ามกับ 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 เข้ามาเก็บ
เป็ นตัวแรกโดยใช้
Push(‘2’)
สแตก Y=[2] ตัว
ชีส้ แตก Top = 2
2
Top
นาค่า 5 เข้ามา
เก็บเป็ นตัวแรก
โดยใช้
Push(‘5’)
สแตก Y=[5]
ตัวชีส้ แตก Top
=5
5
2
Top
นาค่า 3 เข้ามา
เก็บเป็ นตัวแรก
โดยใช้
Push(‘3’)
สแตก Y=[3]
ตัวชีส้ แตก
Top = 3
3
5
2
Top
ต้องการดึงค่า
ออกมาโดยใช้
Pop()
สแตก
Y=[2,5,3]ตัว
ชีส้ แตก
Top = 3
2
5
Top
นาค่า 9 เข้ามา
เก็บเป็ นตัวแรก
โดยใช้
Push(‘9’)
สแตก
Y=[9] ตัว
ชีส้ แตก
Top = 9
9
5
2
Top
นาค่า 0 เข้ามา
เก็บเป็ นตัวแรก
โดยใช้
Push(‘0’)
สแตก Y=[0]
ตัวชีส้ แตก
Top = 0
0
9
5
2
Top
นาค่า 4 เข้ามา
เก็บเป็ นตัวแรก
โดยใช้
Push(‘4’)
สแตก Y=[4]
ตัวชีส้ แตก
Top = 4
4
0
9
5
2
Top
นาค่า 6 เข้ามา
เก็บเป็ นตัวแรก
โดยใช้
Push(‘6’)
สแตก Y=[6]
ตัวชีส้ แตก
Top = 6
6
4
0
9
5
2
Top
 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 use an array to implement a stack first
 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
 การนาข้อมูลเข้าและออกจากหน่ วยความจาด้วยแถวลาดับ ก็เหมือนกับทีย่ กตัวอย่าง
ไปแล้ว
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
};
 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
 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.
 void Push(const double 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(const double x) {
if (IsFull())
cout << "Error: the stack is full." << endl;
else
values[++top]
=
x;
}
 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--];
}
}
 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];
}
 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;
}
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 มีการประยุกต์ใช้มากในการเขียนโปรแกรมของสาขา
วิทยาการคอมพิวเตอร์ เช่น
 การจัดสรรหน่วยความจาในการประมวลผลโปรแกรม (Function Call)
 รวมทัง้ โปรแกรมเรียกใช้ตวั เอง (Recursive)
 การตรวจสอบอักขระสมดุล(Balancing Symbol)
 การคานวณนิพจน์คณิตศาสตร์
 การเรียกใช้ 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
Example :
{x+(y-[a+b])*c-[(d+e)]}/(h-(j-(k-[l-n])))







ในการตรวจสอบอักขระสมดุลนัน้ คอมไพเลอร์ได้นาแนวคิด
โครงสร้างข้อมูลแบบ Stack มาประยุกต์ โดยมีวิธีการดังนี้
1. ให้อ่านอักขระทีละตัว
- ถ้าอักขระเป็ นอักขระเปิด เช่น {,(,[ เป็ นต้น ให้ PUSH ลง
stack
- ถ้าอักขระเป็ นอักขระปิด เช่น },),] เป็ นต้น ให้ตรวจสอบว่า
อักขระบน TOP ของ stack เป็ นอักขระเปิดที่ค่กู นั หรือไม่
- ถ้าใช่ ให้ POP อักขระนัน้ ออกจาก stack
- ถ้าไม่ใช่ ให้แสดงผล error
2.เมื่ออ่านอักขระหมดแล้ว แต่ stack ไม่เป็ น stack ว่าง ให้แสดงผล
error
Download