โครงสร้างข้อมูลแบบกองซ้อน (Stack)
ความหมาย โครงสร้างข้อมูลแบบเชิงเส้นที่ประกอบด้วยกลุ่มของข้อมูลที่มีลำดับ (An Ordered group of items) ที่มีลักษณะดังนี้ การเพิ่มข้อมูลใหม่ในสแตก หรือ การนำข้อมูลออกจากสแตก จะกระทำที่ปลายด้านเดียวกันของสแตก เรียกโครงสร้างแบบนี้ว่า LIFO (Last in first out)
ตัวอย่าง โครงสร้างสแตกในชีวิตประจำวัน
การดำเนินการกับสแตก การเพิ่มข้อมูลลงสแตก เรียกว่า push เช่น push(A) หมายถึงนำ A ใส่ลงสแตก push(N) หมายถึงนำ N ใส่ลงสแตก top N A Top เป็นตัวชี้ตำแหน่งของสมาชิกตัวบนสุดของสแตก
การดำเนินการกับสแตก (ต่อ) การนำข้อมูลออกจากสแตก เรียกว่า pop เช่น pop() หมายถึง นำสมาชิกตัวบนสุดออกจากสแตก top N top A A ก่อน pop() หลัง pop()
การ Implement สแตก Implement ด้วยอาร์เรย์ Implement ลิงค์ลิสต์
การ Implement สแตกด้วยอาร์เรย์ ข้อจำกัดของอาร์เรย์ คือ จำนวนสมาชิก จำกัด ตามขนาดของอาร์เรย์ เช่น ถ้าใช้อาร์เรย์ขนาด 10 ช่อง แทน สแตก จำนวนสมาชิกสูงสุดของ สแตกจะถูกจำกัดแค่ 10 ตัว ไม่สามารถใส่ตัวที่ 11 , 12 ลงไปได้ ซึ่งจะส่งผลต่อ อัลกอริทึม push ในการเพิ่มข้อมูลลงสแตก ส่วนการนำข้อมูลออกจากสแตก ถ้าสแตกว่าง (อาร์เรย์ยังไม่มีข้อมูล) ก็จะไม่สามารถ pop ได้ เพราะไม่มีข้อมูลให้ pop
อัลกอริทึมในการ push 1.ตรวจสอบว่าสแคกเต็มหรือไม่ ถ้าสแตกเต็ม แจ้งข้อความ stack overflow ถ้าสแตกไม่เต็ม ทำข้อ 2 2. เพิ่มค่า top แล้วนำข้อมูลใส่ในตำแหน่งที่ top ของอาร์เรย์
ตัวอย่าง ฟังก์ชัน push ในภาษา C void push(stack *ps , int x) { if(ps->top == STACKSIZE-1) printf(“%s”,”stack overflow”); exit(1); } ps->items[++(ps->top)]=x;
อัลกอริทึมในการ pop 1. ตรวจสอบว่า สแตก ว่างหรือไม่ ถ้าสแตกว่าง ให้แสดงข้อความ stack underflow ถ้าสแตกไม่ว่าง ทำข้อ 2 2. ดึงสมาชิกตัวบนออก แล้วลดค่าตำแหน่ง top ลง 1
ตัวอย่าง ฟังก์ชัน pop ในภาษา C int pop(stack *ps) { if (ps->top == -1) printf(“$s”,”stack under flow”); exit(1); } return (ps->items[ps->top--]);
นิพจน์ infix , prefix , postfix นิพจน์ infix เป็นนิพจน์ที่ operator อยู่ระหว่าง operand เช่น A+B-C นิพจน์ prefix เป็นนิพจน์ที่ operator อยู่หน้า operand เช่น -+ABC นิพจน์ postfix เป็นนิพจน์ที่ operator อยู่หลัง operand เช่น AB+C-
การแปลงนิพจน์ infix เป็นนิพจน์ prefix ให้แปลงตามลำดับค่า Precedence ของ operator โดยนำเครื่องหมายของ operator ไปวางหน้าคู่ของ operand ที่กระทำกัน เช่น A+B แปลงเป็นนิพจน์ Prefix ได้ +AB A+B*C แปลงเป็นนิพจน์ Prefix ได้ +A*BC
การแปลงนิพจน์ infix เป็นนิพจน์ postfix ให้แปลงตามลำดับค่า Precedence ของ operator โดยนำเครื่องหมายของ operator ไปวางหลังคู่ของ operand ที่กระทำกัน เช่น A-B+C แปลงเป็นนิพจน์ postfix ได้ AB-C+
ตัวอย่าง จงแปลงนิพจน์ ให้อยู่ในรูปนิพจน์ prefix และ postfix (A-B*C)/D+E^F-G
การนำสแตกมาใช้ในการแปลงนิพจน์ infix เป็นนิพจน์ postfix 1. ถ้าค่า input เป็น operand ให้นำค่าไปเป็น Output 2. ถ้าค่า input เป็น operator (เครื่องหมายคณิตศาสตร์) ให้พิจารณาดังนี้ 2.1 ถ้า สแตกว่าง ให้นำ operator ใส่สแตก 2.2 ถ้า สแตกไม่ว่าง ให้นำ operator ไปเปรียบกับค่า operator ตัวบนในสแตก ถ้าค่า operator ที่เป็น input มีค่า precedence น้อยกว่าหรือเท่ากับค่า operator ตัวบนของสแตก ให้ดึง operator ตัวบนในสแตกไปเป็น output แล้วเปรียบเทียบกับ operator ในสแตกตัวถัดไป แล้วเปรียบเทียบเช่นเดียวกับก่อนหน้านี้ แต่ถ้า operator ที่เป็น input มีค่า precedence มากกว่าค่า operator ตัวบนของสแตก ให้นำค่า operator ที่เป็น input ใส่สแตก
การนำสแตกมาใช้ในการแปลงนิพจน์ infix เป็นนิพจน์ postfix (ต่อ) 3. ถ้า input เป็น ( ให้ใส่ลงสแตก 4. ถ้า input เป็น ) ให้ดึงข้อมูลออกจากสแตกทีละตัวไปเป็น output จนกระทั่งพบ ( ในสแตก ให้ดึงออกมาทิ้งไป ไม่ต้องไปใส่เป็น output 5. ถ้า input หมด และสแตกยังมีข้อมูลอยู่ ให้ดึงข้อมูลออกจาก stack ที่ตัวไปเป็น output จนกระทั่งสแตกว่าง
จงแปลงนิพจน์ ให้อยู่ในรูปนิพจน์ prefix และ postfix (A-B*C)/D+E^F-G
การแปลงนิพจน์ prefix เป็นนิพจน์ infix ให้พิจารณา คู่ operand ที่กระทำกัน แล้วนำ operator หน้า operand คู่นั้น ไปวางไว้ระหว่าง operand คู่นั้น แล้วพิจาณา นำ operand คู่ถัดไป แล้วทำเช่นเดียวกัน +AB แปลงเป็น infix ได้ A+B +A*BC แปลงเป็น infix ได้ +A(B*C) =A+(B*C)
การแปลงนิพจน์ postfix เป็นนิพจน์ infix ให้พิจารณา คู่ operand ที่กระทำกัน แล้วนำ operator หลัง operand คู่นั้น ไปวางไว้ระหว่าง operand คู่นั้น แล้วพิจาณา นำ operand คู่ถัดไป แล้วทำเช่นเดียวกัน ABC/+ แปลงเป็นนิพจน์ infix ได้ A(B/C)+ = A+B/C
การหาค่านิพจน์ postfix เช่น กำหนด A=10 , B=5 , C=2 จงหาค่าของนิพจน์ ABC-+