1 / 33

Trees ADT

Trees ADT. การเข้าถึงข้อมูลที่มีโครงสร้างแบบ Linked List ซึ่งความสัมพันธ์ระหว่างข้อมูลแต่ละตัวเป็นแบบก่อน (Before) และหลัง (After) Linked List ให้ Running Time เป็นแบบ Linear, O(N) เมื่อจำนวน Input (N) มากๆ Running Time อาจจะมากเกินควร

Download Presentation

Trees ADT

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. TreesADT • การเข้าถึงข้อมูลที่มีโครงสร้างแบบ Linked List ซึ่งความสัมพันธ์ระหว่างข้อมูลแต่ละตัวเป็นแบบก่อน (Before) และหลัง (After) • Linked List ให้ Running Time เป็นแบบ Linear, O(N) • เมื่อจำนวน Input (N) มากๆ Running Time อาจจะมากเกินควร • โครงสร้างข้อมูลแบบต้นไม้ หรือ Trees ซึ่งเป็นโครงสร้างข้อมูลแบบง่ายที่ให้ Running Time เป็น O(log N)โดยเฉลี่ย ซึ่งเป็นการทำงานที่ใช้เวลาน้อยกว่ามาก Week 09 - Tree ADT

  2. โครงสร้างของ Trees ADT • Tree เป็น Abstract Data Type ที่เก็บสมาชิกเป็นแบบลำดับชั้น(Hierarchical) • ความสัมพันธ์ระหว่างข้อมูลแต่ละตัวในโครงสร้างข้อมูลแบบ Trees จะเป็นแบบลำดับขั้น ซึ่งสมาชิกบางตัวอยู่เหนือ (above) สมาชิกอื่น และสมาชิกบางตัวอยู่ใต้ (below) สมาชิกอื่น • ทำงานแบบ nonlinear ซึ่งเป็นวิธีการที่ทำให้เราสามารถสร้าง Algorithm ที่ทำงานได้เร็วขึ้นมาก • ยกเว้นแต่สมาชิกที่อยู่บนสุด (Top Element) สมาชิกตัวอื่นๆแต่ละตัวจะมีสมาชิกแม่ (Parent) และสมาชิกลูก (Child) 0 ตัวหรือมากกว่า • สมาชิกตัวบนสุด (Top Element) ว่า Root ของ Tree Week 09 - Tree ADT

  3. ตัวอย่างการประยุกต์ใช้งาน Tree ใช้ Trees ในการทำงานต่อไปนี้ • ใช้ในการสร้างระบบไฟล์ (File System) ใน Operating System • ใช้ในการประเมินนิพจน์ทางคณิตศาสตร์ (Arithmetic Expressions) • ใช้ช่วยในการหาข้อมูล (Search) เพื่อให้ได้เวลาโดยเฉลี่ยในการหาข้อมูล (Search) เป็น O(log N) และปรับปรุงวิธีการหาข้อมูล (Search) เพื่อให้ได้กรณีที่เลวร้ายที่สูด (Worst-Case) ในการหาข้อมูล (Search) ใช้เวลาไม่เกิน O(log N) Week 09 - Tree ADT

  4. คุณสมบัติพื้นฐานของ Trees • จากนิยามแบบรีเคอร์ซีพ Tree เป็นชุด (Collection) ของ Nodes ซึ่งอาจเป็นศูนย์ (Empty) • Tree ประกอบด้วย Node หลัก Node r เรียกว่า Root หรือรากของต้นไม้ และมี ต้นไม้ย่อยหรือ Subtrees T1, T2, …, Tk • Subtree แต่ละอันจะถูกเชื่อมต่อด้วย Edge โดยตรงจาก Node r • Root ของแต่ละ Subtree ถือว่าเป็น Child ของ r และเรียกได้ว่า r เป็น Parent ของ Subtree แต่ละตัว Edge Subtree Week 09 - Tree ADT

  5. Tree เป็นชุด (Collection) ของ Node จำนวน N nodes • มีกิ่งหรือ Edges ทั้งหมด N – 1 กิ่ง โดยแต่ละกิ่งทำหน้าที่เชื่อม Nodes เข้ากับ Parent ของมัน • ทุก Node ยกเว้น Root จะ Parent 1 ตัว ยกเว้น Root ซึ่งไม่มี Parent • จากรูป Node A เป็น Root ของ Tree นี้ Week 09 - Tree ADT

  6. แต่ละ Node มี Child จำนวนหนึ่ง ซึ่งอาจเป็น 0 • Node ที่ไม่มี Children เรียกว่า Leave หรือใบของต้นไม้ • Node ที่มี Parent เดียวกันเรียกว่าเป็น Siblings (พี่น้อง) กัน Week 09 - Tree ADT

  7. Path หมายถึงเส้นทาง เช่นจาก node n1 ไปยัง nk โดยที่ ni เป็น parent ของ ni+1 สำหรับ 1≤ i < k • Length หมายถึงระยะทางของ Path นี้ซึ่งก็คือจำนวนกิ่ง (Edge) บน path คิดเป็น k – 1 • สังเกตได้ว่า ใน Tree หนึ่งๆ จะมี path 1 path จาก Root Week 09 - Tree ADT

  8. Depth ของ ni หมายถึง Length ของ path เฉพาะจาก Root มาถึง ni ดังนั้นถือได้ว่า Depth ของ Root เป็น 0 • Height ของ ni หมายถึง Length ของ path ที่ยาวที่สุดจาก ni ไปยัง Leave ของ Tree ดังนั้นถือได้ว่า Leave ทุกตัวอยู่ที่ Height ที่ 0 Week 09 - Tree ADT

  9. Height ของ Tree เท่ากับค่า height ของ Root • Depth ของ Tree เท่ากับค่า depth ของ leave ที่อยู่ลึกที่สุด ซึ่งจะมีค่าเท่ากับ Height ของ Tree เสมอ • ถ้ามี Path จาก n1 ไปยัง n2 แสดงว่า • n1 เป็น Ancestor(บรรพบุรุษ)ของ n2 • n2 เป็น Descendant(ลูกหลาน) ของ n1 Week 09 - Tree ADT

  10. การสร้างโครงสร้างข้อมูลแบบTreeการสร้างโครงสร้างข้อมูลแบบTree วิธีการหนึ่งในการสร้าง Trees คือการสร้าง Node โดยแต่ละNode มีองค์ประกอบต่อไปนี้ • ข้อมูล • Pointer ไปยัง Childของ Node นั้นๆ • เนื่องจากไม่มีการกำหนดจำนวน Child ของแต่ละ Node ไว้ล่วงหน้า การสร้าง Pointer เพื่อเชื่อมไปยัง Child แต่ละตัวโดยตรงจะทำให้เสียเนื้อที่มาก • ทางออกอย่างง่ายๆคือการเก็บ Child ของแต่ละ Node ไว้ใน Linked Listที่เก็บโหนดต่างๆของต้นไม้ Week 09 - Tree ADT

  11. struct TreeNode { string element ; TreeNode* firstChild ; TreeNode* nextSibling ; } element nextSibling firstChild • firstChild คือ Pointer ที่ชี้ลงด้านล่าง • nextSibling คือPointer ที่ชี้จากซ้ายไปขวา • NULL Pointer จะไม่ได้วาดเอาไว้เนื่องจากมีเป็นจำนวนมาก Week 09 - Tree ADT

  12. การเดินทางใน Tree (Tree Traversal) • Traversal สำหรับ Tree คือระบบวิธีในการเข้าถึง (access/ visit) สมาชิก Nodes ทั้งหมดที่มีอยู่ใน Tree • พิจารณา Tree ที่เป็นโครงสร้างไดเร็กทอรีของ Operating System ทั่วไป เช่นโครงสร้างระบบไฟล์ใน UNIX Week 09 - Tree ADT

  13. Root Directory ของคือ Node /usr • /usr มี Children ทั้งหมด 3 ตัว ได้แก่ mark, alex และ bill ซึ่งล้วนเป็น Directory เช่นเดียวกัน ดังนั้น เรียกได้ว่า /usr ประกอบด้วย directories 3 อันแต่ไม่มี file • File ที่ชื่อว่า /usr/mark/book/ch1.r ได้มาจากการไล่ไปตาม child ตัวซ้ายสุด 3 ครั้ง Week 09 - Tree ADT

  14. พิจารณา /usr/mark/book/ch1.r เครื่องหมาย / แต่ละอันหลังจากอันแรก แสดง Edge แต่ละกิ่ง ผลลัพธ์ที่ได้คือชื่อเต็มของ pathname • ระบบไฟล์แบบลำดับขั้น (Hierarchical File System) • File ใน directory ต่างกันสามารถมีชื่อซ้ำกันได้ เนื่องจากมี path จาก root ต่างกันซึ่งทำให้มี pathname ที่ต่างกันไป Week 09 - Tree ADT

  15. Directory Listing • แสดงรายชื่อของ Files ทั้งหมดใน directory ออกมา • File ที่มี Depth di จะถูกแท็บ (Tab) ย่อหน้า (indent) เข้าไป di แท็บ ListDir (DirectoryOrFile D, int Depth) { PrintName(D, Depth); if(D is a directory) for each child, C, of D ListDir(C, Depth+1); } main() { … ListDir(D, 0); } Week 09 - Tree ADT

  16. ListDir (DirectoryOrFile D, int Depth) { PrintName(D, Depth); if(D is a directory) for each child, C, of D ListDir (C, Depth+1); } main() { … ListDir (D, 0); } • ใช้ Recursive Function ที่ชื่อ ListDir • ค่าอาร์กิวเมนต์ที่ส่งให้กับ ListDir เป็นค่าอ้างอิงไปยัง Tree ได้แก่ชื่อDirectory หรือ File ที่ต้องการแสดงชื่อ และ ค่า Depth ของ Directory หรือ File นั้นๆ ซึ่งบ่งบอกถึงจำนวน tab ที่ต้องแสดง Week 09 - Tree ADT

  17. ListDir (DirectoryOrFile D, int Depth) { PrintName(D, Depth); if(D is a directory) for each child, C, of D ListDir(C, Depth+1); } main() { … ListDir(D, 0); } ชื่อของ Directory หรือ File จะถูก print ออกพร้อมกับจำนวน Tabs ที่ต้องการ print ไว้ด้านหน้า • Printname ซึ่งมีพารามิเตอร์คือ ชื่อ File/Directory และ จำนวน Tab ที่ต้องแสดงก่อนหน้าชื่อ ซึ่งระบุโดย Depth • ถ้าอาร์กิวเมนต์ที่ส่งให้กับ ListDir เป็น Directory ฟังก์ชั่นจะทำการเรียกตัวเองเพื่อทำงานแบบ Recursive กับ Child ทุกตัวของ Directory นั้นๆทีละตัว แต่เนื่องจาก Child เหล่านี้มี Depth เพิ่มขึ้น 1 ค่าจึงต้องการ Tab เพิ่มขึ้นเป็น Depth + 1 Week 09 - Tree ADT

  18. วิธีการท่อง Tree แบบนี้เรียกว่า Tree Traversal แบบ Preorder Week 09 - Tree ADT

  19. Tree Traversal • Preorder Traversal:Root ของ Tree จะถูก visit ก่อน จากนั้นจึงค่อย visit Subtrees ที่เป็น root ของ child แต่ละตัว โดยงานที่ต้องกระทำกับ Node จะทำก่อน (pre) ที่จะเลื่อนไป visit Child ของ Node นั้นๆ • Postorder Traversal:Subtrees ที่เป็น root ของ child แต่ละตัวจะถูก visit แบบ recursive ก่อนที่จะ visit ตัว Root โดยงานที่ต้องกระทำกับ Node จะทำหลัง (post) จากที่ visit Child ของ Node และทำงานบน Child ของ Node นั้นๆหมดแล้ว Week 09 - Tree ADT

  20. Preorder Traversal Week 09 - Tree ADT

  21. Postorder Traversal Week 09 - Tree ADT

  22. Binary Tree • Binary Tree หมายถึง Tree ที่แต่ละ Node ไม่สามารถมี Child ได้เกินกว่า 2 ตัว • Binary Tree ที่ประกอบด้วย Root และ Subtree 2 อันคือ TL และ TR ซึ่งทั้งคู่อาจจะเป็น Tree ว่างก็ได้ Week 09 - Tree ADT

  23. Depth ของ Binary Tree โดยเฉลี่ยจะมีค่าน้อยกว่า N ค่อนข้างมาก • ค่า Depth เฉลี่ยอยู่ที่ O(√N) • ค่า Depth มีอาจสูงถึง N-1 ก็ได้เช่นเมื่อ Tree มีลักษณะดังรูป Week 09 - Tree ADT

  24. การสร้างต้นไม้แบบทวิภาค (Binary Tree Implementation) • Binary Tree สามารถมี Child ได้มากที่สุดเพียงแค่ 2 ตัว จึงสามารถสร้าง Pointer ไปยัง Child แต่ละตัวได้โดยตรง • Node มีโครงสร้างเป็นแบบ Structure ที่ประกอบด้วยส่วน Key element เพื่อเก็บข้อมูล และ Pointer 2 ตัว (Left และ Right) เพื่อชี้ไปยัง Nodes อื่น struct TreeNode { string element ; TreeNode* left ; TreeNode* right ; } left element right Week 09 - Tree ADT

  25. การประยุกต์ใช้งาน Binary Treeต้นไม้ของนิพจน์ทางคณิตศาสตร์ (Expression Tree) • เราสามารถแทนนิพจน์ทางคณิตศาสตร์ด้วยโครงสร้างข้อมูลแบบต้นไม้ได้ เช่นแทน ((A*B) + C) + ((D + (E / F)) - G) Week 09 - Tree ADT

  26. ต้นไม้ของนิพจน์ทางคณิตศาสตร์ (Expression Tree) • โหนดใบ (Leave)ของ Expression Tree คือ Operands(ตัวถูกดำเนินการ) ได้แก่ค่าคงที่ (Constant) หรือตัวแปร (Variable) • โหนดอื่นๆบรรจุ Operators (ตัวดำเนินการ) Week 09 - Tree ADT

  27. การคำนวณหาค่าของ Expression Tree หาค่าของ Infix expression (อาจรวมวงเล็บด้วย) ได้โดย • หาค่าของนิพจน์ทางคณิตศาสตร์ (Expression) พร้อมวงเล็บ ของ subtree หรือ tree ทางด้านซ้ายด้วยวิธีแบบ recursive • แสดงค่า Operator ที่ Root ของ subtree/tree ออกมา • หาค่าของนิพจน์ทางคณิตศาสตร์ (Expression) พร้อมวงเล็บ ของ subtree หรือ tree ทางด้านขวาด้วยวิธีแบบ recursive • วิธีการที่กระทำการบนสมาชิกทางด้านซ้ายของโหนดก่อนตัวโหนด แล้วตามการกระทำบนสมาชิกทางด้านขวาของโหนด (Left, Node, Right) นี้เรียกว่า Inorder Traversal Week 09 - Tree ADT

  28. การคำนวณหาค่าของ Expression Tree Inorder Traversal (Left, Node, Right) • ให้ Infix Expression ((A*B)+C)+((D+(E/F))-G) Postorder Traversal (Left, Right, Node) • ให้ Postfix Expression AB*C+DEF/+G-+ Preorder Traversal (Node, Left, Right) • ให้ Prefix Expression ++*ABC-+D/EFG Week 09 - Tree ADT

  29. การคำนวณหาค่าของ Expression Tree Infix Expression Postfix Expression Prefix Expression (A + (B/C)) + ((D*E)+((F-G)*H)) A B C / + D E * F G – H * + + + + A / B C + * D E * - F G H Week 09 - Tree ADT

  30. การสร้างต้นไม้ของนิพจน์ทางคณิตศาสตร์ การเปลี่ยน Postfix Expression เป็น Expression Tree • อ่านนิพจน์ทางคณิตศาสตร์ (Expression) เข้ามาทีละตัว • ถ้าอักษรที่ได้เป็น Operand (ตัวถูกดำเนินการ) ให้สร้างต้นไม้ขนาด 1 โหนด แล้ว push พอยน์เตอร์ 1 อันลงบนสแตก • ถ้าอักษรที่ได้เป็น Operator (ตัวดำเนินการ) ให้ pop พอยน์เตอร์ไปยังต้นไม้ 2 อันคือ T1 และ T2 ออกมาจากสแตกแล้วสร้างต้นไม้ใหม่ขึ้นหนึ่งอันให้มี Root อยู่ที่ Operator ที่รับเข้ามาและมี Child ด้านซ้ายและด้านขวา เป็น T1 และ T2 ตามลำดับ • พอยน์เตอร์ที่ชี้ไปยังต้นไม้ที่สร้างขึ้นมาใหม่นี้ จะถูก Push ลงไปบนสแตก Week 09 - Tree ADT

  31. Inputa b + c d e + * * a b + c d e + * * • Input 2 ตัวแรกเป็น Operand จึงสร้างต้นไม้ขนาด 1 โหนดแล้ว push พอยน์เตอร์ 1 อันลงบนสแตก a b + c d e + * * • อ่าน + เข้ามา จึง pop พอยน์เตอร์ออกมาจากสแตก สร้างต้นไม้ใหม่ Push พอยน์เตอร์ที่ชี้ไปยังต้นไม้ที่สร้างขึ้นมาใหม่ลงไปบนสแตก Week 09 - Tree ADT

  32. a b + c d e + * * • อ่าน c, d, e เข้ามา สร้างต้นไม้ขนาด 1 โหนด สำหรับอักษรแต่ละตัว แล้ว Push พอยน์เตอร์ที่ชี้ไปยังต้นไม้ แต่ละอันนี้ลงบนสแตก a b + c d e + * * • อ่าน + เข้ามา จึง pop พอยน์เตอร์ออกมาจากสแตก สร้างต้นไม้ใหม่ Push พอยน์เตอร์ที่ชี้ไปยังต้นไม้ที่สร้างขึ้นมาใหม่ลงไปบนสแตก Week 09 - Tree ADT

  33. a b + c d e + * * • อ่าน * เข้ามา จึงทำการ Pop พอยน์เตอร์ออกมาจากสแตก แล้วสร้างต้นไม้ใหม่โดยมี * ที่อ่านเข้ามาเป็น Root a b + c d e + * * • อ่าน * เข้ามา ทำการ Pop พอยน์เตอร์ออกมาจากสแตก แล้วสร้างต้นไม้ใหม่โดยมี * ที่อ่านเข้ามาเป็น Root Week 09 - Tree ADT

More Related