590 likes | 945 Views
วิชา COSC2202 โครงสร้างข้อมูล (Data Structure). โครงสร้างข้อมูลแบบ Stack และ Queue โครงสร้างข้อมูลแบบ Tree. โครงสร้างข้อมูลแบบ Stack.
E N D
วิชา COSC2202โครงสร้างข้อมูล (Data Structure) โครงสร้างข้อมูลแบบ Stack และ Queue โครงสร้างข้อมูลแบบ Tree
โครงสร้างข้อมูลแบบ Stack • สแตกเป็นโครงสร้างข้อมูลแบบลิเนียร์ลิสต์(linear list) ที่สามารถนำข้อมูลเข้าหรือออกได้ทางเดียวคือส่วนบนของสแตกหรือ หรือเรียกว่า ท๊อปของสแตก (Top Of Stack) ซึ่งคุณสมบัติดังกล่าวเรียกว่า ไลโฟลิสต์ (LIFO list: Last-In-First-Out list) หรือ พูชดาวน์ลิสต์ (Pushdown List) คือสมาชิกที่เข้าลิสต์ที่หลังสุดจะได้ออกจากลิสต์ก่อน หรือ เข้าหลังออกก่อน การเพิ่มข้อมูลเข้าสแตกจะเรียกว่าพูชชิ่ง (pushing) การนำข้อมูลจากสแตกเรียกว่า ป๊อปปิ้ง (poping) การเพิ่มหรือลบข้อมูลในสแตกทำที่ท๊อปของสแตก ท๊อปของสแตกนี้เองเป็นตัวชี้สมาชิกตัวท้ายสุดของสแตก
Pop คือ การนำข้อมูลออกจากส่วนบนสุดของสแตก Push คือ การนำข้อมูลใส่ลงไป ในสแตก โครงสร้างข้อมูลแบบ Stack • ตัวอย่างการทำงานแบบโครงสร้างข้อมูลแบบสแตก
นิพจน์ทางคณิตศาสตร์ • ในการเขียนนิพจน์ทางคณิตศาสตร์เพื่อการคำนวณจะต้องคำนึงถึงลำดับความสำคัญของเครื่องหมายสำหรับการคำนวณด้วยโดยทั่วไปนิพจน์ทางคณิตศาสตร์สามารถเขียนได้ 3 รูปแบบ คือ 1.นิพจน์ Infix นิพจน์รูปแบบนี้ operator จะอยู่ตรงกลางระหว่างตัวถูกดำเนินการ 2 ตัว เช่น A+B*C-D/E 2.นิพจน์ Postfix นิพจน์รูปแบบนี้ จะต้องเขียนตัวถูกดำเนินการตัวที่ 1 และ 2 ก่อน แล้วตามด้วย operator เช่น ABC*+DE/- 3.นิพจน์ Prefix นิพจน์รูปแบบนี้ จะต้องเขียน operator ก่อนแล้วตามด้วยตัวถูกดำเนินการตัวที่ 1 และ 2 เช่น - +A*BC/DE
นิพจน์ทางคณิตศาสตร์ นิพจน์ Infix
การประยุกต์ของสแตก การแปลงนิพจน์ Infix ให้เป็น Postfix ข้อเสียของนิพจน์ infix ทีทำให้คอมไพเลอร์ยุ่งยาก คือลำดับความสำคัญของโอเปอร์เรเตอร์ (Precedence) ที่ต่างกัน เช่นเครื่องหมายยกกำลัง (ใช้ ^ ในการเขียนโปรแกรม) มีความสำคัญมากกว่าเครื่องหมายคูณ และหาร และเครื่องหมายคูณและหารมีความสำคัญมากกว่าเครื่องหมายบวกและลบ • Operator คือเครื่องหมายกระทำ + - * / ^ • Operand คือตัวแปรต่าง ๆ A,B,C,D,E เช่น A+B*C,(A*B)-C
การประยุกต์ของสแตก ลำดับความสำคัญ Operator • เครื่องหมายยกกำลัง ^ • เครื่องหมายคูณกับหาร *,/ • เครื่องหมายบวกกับลบ +,- • เครื่องหมายวงเล็บ () กระทำก่อนเช่น A+(B*C) • เครื่องหมายระดับเดียวกันไม่มีวงเล็บให้ทำจากซ้ายไปขวา เช่น A+B+C
การประยุกต์ของสแตก • เมื่อการประมวลนิพจน์ infix เป็นไปด้วยความยากที่การคำนวณไม่เป็นไปตามลำดับของเครื่องหมายโอเปอร์เรเตอร์ที่มีก่อนหลัง คอมไพเลอร์จึงแปลงนิพจน์ infix ให้เป็น postfix เสียก่อน • นิพจน์ Postfix ก็คือนิพจน์ที่มีโอเปอเรเตอร์อยู่หลังโอเปอร์แรนด์ทั้งสอง เช่น AB+ หมายถึง A+B AB- หมายถึง A-B AB* หมายถึง A*B
การแปลงนิพจน์ Infix ให้เป็น Postfix • เราสามารถแปลงนิพจน์Infix ให้เป็น Postfix ได้โดยอาศัยสแตคที่มีคุณสมบัติการเข้าหลังออกก่อนหรือ LIFO โดยมีอัลกอริทึมในการแปลงนิพจน์ ดังนี้พิจารณาทีละตัว - ถ้าเป็น Operand ให้ส่งไป Output - ถ้าเป็น ( ให้ Push ลง Stack - ถ้าเป็น ) ให้ Pop ไป Output จนกว่าจะเป็น ( - ถ้าเป็น Operator ให้ Pop ไป Output จนกว่า Priority จะมากกว่า Priority(StackTop) แล้วจึง Push ลง Stack เมื่อครบทุกตัวแล้วให้ Pop ไปที่ Output จนหมด
การแปลงนิพจน์ Infix ให้เป็น Postfix ตัวอย่างการแปลงนิพจน์ Infix เป็นนิพจน์ Postfix นิพจน์ A + B * C
ตัวอย่าง นิพจน์ (A * B) + (C / D)
ตัวอย่าง นิพจน์ A / B + (C – D)
ตัวอย่าง นิพจน์ (A + B) * ( C ^ D – E ) * F
การแปลงนิพจน์ Infix ให้เป็น Postfix ทำด้วยมือ: 1. ใส่วงเล็บเพื่อกำหนดลำดับการประมวลผล 2. เปลี่ยน (A @ B)เป็น (A B @)ทีละวงเล็บ โดยทำจากวงเล็บในสุดก่อน 3. ดึงวงเล็บออกทั้งหมด
ตัวอย่าง • นิพจน์ (A + B) * ( C ^ D – E ) * F ( ( A + B ) * ( ( C ^ D ) – E ) ) * F ( ( A B + ) * ( ( C D ^ ) – E ) ) * F ( ( A B + ) * ( C D ^ E - ) ) * F ( A B + C D ^ E - * ) * F A B + C D ^ E - * F *
ตัวอย่าง การคำนวณหาค่า ของนิพจน์ Postfix
โครงสร้างข้อมูลแบบ Queue • คิวเป็นโครงสร้างข้อมูลแบบลำดับ (Sequential) ลักษณะของคิวเราสามารถพบได้ในชีวิตประจำวัน เช่น การเข้าแถวตามคิวเพื่อรอรับบริการต่างๆ ซึ่งจะเห็นได้ว่าลักษณะของการทำงานจะเป็นแบบใครมาเข้าคิวก่อน จะได้รับบริการก่อน เรียกได้ว่าเป็นลักษณะการทำงานแบบ FIFO (First In , First Out)
โครงสร้างข้อมูลแบบ Queue • ลักษณะของคิว จะมีปลายสองข้าง ซึ่งข้างหนึ่งจะเป็นช่องทางสำหรับข้อมูลเข้าที่เรียกว่า REAR และอีกข้างหนึ่งซึ่งจะเป็นช่องทางสำหรับข้อมูลออก เรียกว่า FRONT • การเอาข้อมูลเข้าไปใน Queue จะเรียกว่าการ Enqueue • การเอาข้อมูลออกจาก Queue จะเรียกว่าการ Dequeue
ตัวอย่าง คิวที่ใช้อาร์เรย์ขนาด 5 โดยเพิ่มค่า 70, 80 และ 50 ในรูป (a) จากนั้นดึงออกมา 2 ค่า ได้เป็นรูป (b) และเพิ่มค่า 90,60 ในรูป (c) คิวเต็มแล้ว.. เพิ่มค่าไม่ได้...
โครงสร้างข้อมูลแบบ Queue • แทนที่จะใช้คิวเป็นเชิงเส้นแบบแนวตรง ก็มาใช้เป็นคิววงกลม (Circular Queue) ในลักษณะของเส้นรูปวงแหวนเพื่อแก้ไขปัญหาดังกล่าว โดยสมมุติให้อาร์เรย์เป็นวงกลมที่สมาชิกตัวแรกต่อจากสมาชิกตัวสุดท้าย เมื่อเก็บค่าถึงสมาชิกตัวสุดท้ายก็จะเก็บวนต่อไปยังสมาชิกตัวแรก ดังนั้น ในการเพิ่มค่าให้กับ Front และ Rear จะอยู่ในขอบเขตขนาดของอาร์เรย์และให้สมาชิกที่เข้ามาต่อจากตำแหน่งสุดท้ายของอาร์เรย์วนกลับไปยังตำแหน่งแรก
คิววงกลม (Circular Queue) • สิ่งที่ต้องพิจารณาเมื่อคิวว่างเปล่าสามารถทราบได้จาก Front กับ Rear มีค่าเท่ากัน เช่น เดียวกันเมื่อคิวเต็ม Rear จะวนกลับมาจนมีค่าเท่ากับ Front ทำให้เกิดความสับสนได้ว่าเมื่อ Front และ Rear มีค่าเท่ากันจะเป็นสถานะของคิวว่างหรือคิวเต็ม อย่างไรก็ตามสามารถหลีกเลี่ยงปัญหานี้ได้โดยให้สมาชิกที่อยู่ก่อนหน้าสมาชิกในตำแหน่ง Front เป็นตำแหน่งช่องว่างเสมอ คิวเต็มก็ต่อเมื่อ (Rear+1) modmaxSize = Front (mod คือการหารเอาเศษ)
การคำนวณนิพจน์แบบ Prefix • ใส่ข้อมูลลงใน Queue • ถ้าเป็น Operator และตามด้วย Operand อีก 2 ตัว ให้คำนวณค่าก่อนแล้วใส่ค่าที่ได้ลง Queue • เมื่อข้อมูลหมดก็ให้เริ่มทำใหม่จนกว่าจะได้ผลลัพธ์สุดท้าย
ตัวอย่าง จงหาผลลัพธ์ของนิพจน์ Prefix ต่อไปนี้ - + * 9 + 2 8 * + 4 8 6 3 - + * 9 10 * 12 6 3 - + 90 72 3 - 162 3 Result = 159
โครงสร้างข้อมูลแบบต้นไม้ (Tree) นิยามโครงสร้างต้นไม้ (Tree)เป็นโครงสร้างชนิดไม่เชิงเส้น (Non-linear) มีลักษณะเป็นรีเคอร์ซีฟ - Tree เป็นกลุ่มของโหนดที่มีสมาชิกหนึ่งโหนดหรือมากกว่า โดยที่ - มีโหนดพิเศษโหนดหนึ่งเรียกว่า Root Node - โหนดอื่นๆ จะถูกแบ่งออกเป็นเซตที่ไม่มี สมาชิกร่วมกันซึ่งแต่ละเซตจะมีโครงสร้างเป็น Tree ที่เรียกว่า Subtree ของ Root Node
R Root Nodes A B X C D H Y E I G โครงสร้างต้นไม้ (Tree Structure) Nodes X เป็น Immediate Predecessor ของ Y หรือ X เป็น Father (Parent) ของ Y Nodes Y เป็น Immediate Successor ของ X หรือ Y เป็น son (Child) ของ X Leaf Nodes
Level 0 R Root Nodes A B X Level 1 C D H Y Level 2 E I G Level 3 โครงสร้างต้นไม้ (Tree Structure) Levelแสดงถึงหน่วยระยะทางตามแนวดิ่งของโหนดว่าอยู่ห่างจาก Root Node เป็นระยะเท่าไรและทุกกิ่งมีความยาวเท่ากันคือ 1 หน่วย
โครงสร้างต้นไม้ (Tree Structure) Root • root node โหนดแรกสุดไม่มีข้อมูลก่อนหน้า Leaf • โหนดที่อยู่ปลายสุด ไม่มีข้อมูลตามหลัง Level • ระดับของโหนด ระยะห่างแนวดิ่งจาก root Tree Height • จำนวนระดับของต้นไม้ Sub tree • ต้นไม่ย่อย ส่วนย่อยของต้นไม้ทั้งหมด Height = 4 Sub tree
โครงสร้างต้นไม้ (Tree Structure) Parent / Father • โหนดที่มีระดับอยู่ก่อนหน้าหนึ่งระดับ Child / Son • โหนดที่ตามหลังในระดับถัดไป Sibling / Brother • โหนดที่มี parent เดียวกัน parent child sibling
Predecessor / Ancestor • บรรพบุรุษ โหนดที่อยู่ก่อนหน้า Successor / Descendant • ลูกหลาน โหนดที่อยู่ตามหลัง Ancestor descendant
โครงสร้างต้นไม้ (Tree Structure) Degree • จำนวนลูกหลาน (descendant) ทั้งหมดของโหนดนั้น Degree = 4
การท่องต้นไม้ (Tree Traversal) Tree Traversalหมายถึงการไปยังโหนดเพื่อประมวลผลบางอย่างที่ต้องการกระทำกับโหนดนั้น เช่น หาข่าวสาร แบ่งออกเป็น 3 วิธี (ที่นิยมใช้) 1. Pre-Order Traversal (RTLTR) 2. In-Order Traversal (TLRTR) 3. Post-Order Traversal (TLTRR)
R A X C D G Pre-Order Traversal (RTLTR) start stop Result R A C D X Y G Y
R A X C D G In-Order Traversal (TLRTR) start stop Result C A D R G Y X Y
R A X C D G Post-Order Traversal (TLTRR) start stop Result C D A G Y X R Y
ต้นไม้แบบไบนารี (Binary Tree) • ลักษณะพิเศษของ Binary Tree • ลักษณะทั่วไปเหมือนกันต้นไม้ทั่วไป • มีแค่ Root Node ที่ว่างเปล่า (ไม่มี Son หรือ Child) • มี Root Node และ Subtree 2 กลุ่ม ซึ่งเรียกว่า Left Subtree และ Right Subtree • มี Child ของ Parent ไม่เกินกว่า 2 โหนด
ต้นไม้แบบไบนารี (Binary Tree) • ลักษณะที่ไม่ใช่ต้นไม้แบบไบนารี (Binary Tree) • ต้นไม้ไบนารีที่มีวงจรปิด หรือ Loop
ต้นไม้ไบนารีแบบสมบูรณ์ (Complete Binary Tree) • ลักษณะต้นไม้ไบนารีแบบสมบูรณ์ (Complete Binary Tree) • ต้นไม้ไบนารีสมบูรณ์ คือ ต้นไม้ไบนารีที่โหนดในระดับใดๆ จะมีโหนดเต็มจำนวนเท่ากับ 2nในทุกระดับ คือ 1,2,4,8,16,… • ความสัมพันธ์ระหว่าง Level กับจำนวนโหนดของไบนารีแบบสมบูรณ์ เขียนได้ n = 2l – 1 n = จำนวนโหนดทั้งหมดในต้นไม้ไบนารีแบบสมบูรณ์ l = Level ของต้นไม้ไบนารีแบบสมบูรณ์
ต้นไม้ไบนารีแบบสมบูรณ์ (Complete Binary Tree) n = 23 – 1 = 8 – 1 = 7
การแปลงต้นไม้ทั่วไปเป็นต้นไม้ไบนารีการแปลงต้นไม้ทั่วไปเป็นต้นไม้ไบนารี • ในต้นไม้ทั่วไปโหนดแต่ละโหนดจะมีกี่ SON ก็ได้ ส่วนต้นไม้ไบนารีแต่ละโหนดจะมี SON ได้มากที่สุดเท่ากับ 2 SONs การแปลงต้นไม้ทั่วไปให้เป็นแบบไบนารีจะใช้หลักที่ว่า ในต้นไม้ทั่วไปแต่ละโหนดจะมี SON ที่อยู่ทางซ้ายสุด 1 SON และ SON โหนดนั้นจะมีพี่น้องถัดไป 1 โหนดเท่านั้น • การแปลงนั้นแบ่งได้เป็น 2 ขั้นตอน คือขั้นที่ 1 แปลงต้นไม้ทั่วไปโดยใช้หลักความสัมพันธ์ระหว่างโหนดเป็น leftmost son - next sibilingขั้นที่ 2 หมุนต้นไม้ที่แปลงแล้วไป 45 องศา จะได้ต้นไม้ไบนารีแบบปกติ การแปลงต้นไม้ทั่วไปเป็นแบบไบนารี
ต้นไม้ทั่วไป • แปลงโดยใช้ความสัมพันธ์ leftmost-son และ next- sibling • หลังจากหมุน 45 องศา จะได้ต้นไม้ไบนารีปกติ
การแปลงต้นไม้ทั่วไปเป็นต้นไม้ไบนารีการแปลงต้นไม้ทั่วไปเป็นต้นไม้ไบนารี
Binary Search Tree • มีคุณสมบัติเป็น Binary Tree โดยที่ • ลูกทางซ้ายต้องน้อยกว่า Parent • ลูกทางขวาต้องมากกว่า Parent • ถ้าข้อมูลซ้ำ จะไม่เก็บ 5 2 8 7 11
Binary Search Tree • การใส่ข้อมูลใน Binary Search Tree 15 5 12 20 3 18 10 19 • ทุก Node ทาง Left Sub Tree จะน้อยกว่า Root • ทุก Node ทาง Right Sub Tree จะมากกว่า Root 15 5 20 3 12 18 19 10
Binary Search Tree • ในการค้นหาข้อมูล ทำได้เร็ว คือไม่เกิน Height+1 (ความสูงของ tree+1) เช่น • Tree นี้ Height = 3 สมมุติว่าต้องการหาว่า 19 มีหรือไม่ • จะใช้จำนวนครั้งในการหา = 4 ครั้ง คือที่ Node 15, 20, 18, 19 15 5 20 3 12 18 19 10
แบบฝึกหัด 1.จงเปลี่ยนนิพจน์ Infix ต่อไปนี้เป็น Postfix • A + B * C – D / E • (A - 2 * (B + C) – D * E) * F 2. จงเปลี่ยนนิพจน์ Infix ต่อไปนี้เป็น Prefix (50 - 2 * (2 + 3) - 5 * 4) * 6 3.จงคำนวณหาค่าของนิพจน์ Prefix ที่ได้ในข้อ 2
แบบฝึกหัด • ให้สร้าง Binary Search Tree จากข้อมูลดังนี้ 10, 8, 2, 4, 3, 15, 26, 30 ,17, 6 • จากรูป Tree ที่กำหนดให้ จงเขียนผลลัพธ์จากการท่องไปใน Tree ทั้ง 3 แบบได้แก่ Preorder, Inorder และ Postorder