Lecture9 Tree อ. วรวิทย์ วีระพันธุ์ เรียบเรียงโดย อ
Terminology ต้นไม้ (Tree) ประกอบด้วย 1. Node ใช้เก็บข้อมูล 2. Branch ใช้เชื่อม Node เข้าด้วยกัน A B C Node A, B, C Branch AB, AC
Node A มี Degree เท่ากับ 2 Terminology Degree หมายถึง จำนวน Branch ที่สัมพันธ์กับ Node แบ่งเป็น 1. Indegree หมายถึง Branch ที่เข้าหา Node 2. Outdegree หมายถึง Branch ที่ออกจาก Node A B C Node A มี Degree เท่ากับ 2 Indegree = 0 Outdegree = 2
Terminology Root หมายถึง Node แรกของ Tree Root A B C
ดังนั้นจะพบว่าต้นไม้ทั่วไป Root มี Indegree = อื่นๆ มี Indegree = Root มี Outdegree = อื่นๆ มี Outdegree = N 1 N
Leaf หรือ External node หมายถึง Node ที่มี Outdegree เท่ากับ 0 B C Leaf B, C
Internal node หมายถึง Node ที่ไม่ใช่ Root และ Leaf B C D E Root A Leaf D, E, C Internal node B
Parent หมายถึง Node ที่มี Outdegree B C D E Parent A, B
Child หมายถึง Node ที่มี Indegree A B C D E Child B, C, D, E
Sibling หมายถึง Node ที่มี Parent เดียวกัน C D E Sibling {B, C}, {D, E}
Path หมายถึง เส้นทางจาก Node หนึ่งไปยังอีก Node หนึ่ง B C D E Path จาก A ไป E A -> B -> E ** ทุก Node ใน Tree จะต้องมี Path เดียวเท่านั้น **
Ancestor หมายถึง ทุก Node ในเส้นทางจาก Root ไปยัง Node ที่ต้องการ B C D E Ancestor ของ E A, B
Descendent หมายถึง ทุก Node ในเส้นทางจาก Node ที่กำหนดไปจนถึง Leaf B C D E Descendent ของ A B, C, D, E Descendent ของ B D,E
Level หมายถึง ระยะทางจาก Root A B C D E Level 1 Level 2
Height ของ Tree หมายถึง Level สูงสุด ของ Leaf บวกด้วย 1 B C D E Level 1 Level 2 Height = 2 + 1 = 3
Depth ของ Node หมายถึง ความยาวของ path จาก root node ถึง node นั้น ดังนั้น root node จึงมีความ ลึก (Depth) เป็น 0 Depth ของ Tree หมายถึง ความลึกของ leaf node ที่ อยู่ลึกที่สุด ซึ่งจะมีค่าเท่ากับความสูงของ tree เสมอ
Parents Children Siblings Leaves Internal nodes Ancestor of G Descendent of A Height A,B,F B,E,F,C,D,G,H,I {B,E,F}, {C,D}, {G,H,I} C,D,E,G,H,I B,F A,F B,E,F,C,D,G,H,I 3
Subtree หมายถึง โครงสร้างที่เชื่อมต่อกัน ภายใต้ Root โดย Node แรกของ Subtree จะเป็น Root ของ Subtree นั้น และใช้เป็นชื่อเรียก Subtree Subtree สามารถแบ่งย่อยเป็น Subtree ได้อีกจนกว่าจะ Empty
Subtree
แบบฝึกหัด 1. จากต้นไม้ต่อไปนี้ จงหา 1.1 Root 1.2 Leaves 1.3 Internal nodes 1.4 Ancestors of H 1.5 Descendents of F
2. จากต้นไม้ต่อไปนี้ จงหา 2.1 Indegree of node F 2.2 Outdegree of node G 2.3 Siblings of I 2.4 Parent of G 2.5 Children of C
3. จากต้นไม้ต่อไปนี้ จงหา 3.1 Height of the tree 3.2 Height of subtree G 3.3 Level of node I 3.4 Level of node A 3.5 Height of subtree E
Binary Tree หมายถึง ต้นไม้ที่แต่ละ Node มี Subtree <= 2 หรือ Outdegree <= 2
ตัวอย่าง Binary Tree
Empty หรือ Null Tree
จำนวนเต็มที่มากที่สุดที่น้อยกว่าหรือเท่ากับ log2N Height of Binary Tree คำถามที่ 1 มี Node อยู่ทั้งหมด 7 Nodes 1.1 จะสร้าง Tree ให้มี Height สูงสุดได้เท่าไร อย่างไร 1.2 จะสร้าง Tree ให้มี Height ต่ำสุดได้เท่าไร อย่างไร Hmax = N Hmin = log2N + 1 จำนวนเต็มที่มากที่สุดที่น้อยกว่าหรือเท่ากับ log2N
Nmin = H คำถามที่ 2 Tree ที่มี Height = 3 2.1 จะมี Node สูงสุดได้เท่าไร อย่างไร 2.2 จะมี Node ต่ำสุดได้เท่าไร อย่างไร Nmax = 2H - 1 Nmin = H
Binary Tree ที่มี Node เต็มทุก Level Complete Binary Tree Binary Tree ที่มี Node เต็มทุก Level Nearly Complete Binary Tree Binary Tree ที่มี Node เต็มทุก Level ยกเว้น Level สุดท้าย และ Node ใน Level สุดท้ายอยู่เรียงกันทางซ้ายมือ
Complete และ Nearly Complete Binary Tree
Binary Tree Traversal 1. Depth-first Descendent ทั้งหมดของ Child จะต้องถูก ประมวลผลก่อน Child ถัดไป 2. Breath-first ประมวลผลทีละ Level จากบนลงล่าง
Depth-first N L R L N R L R N
แบบ Preorder วิธีการของ Preorder (val root <node pointer>) N L R วิธีการของ Preorder (val root <node pointer>) 1 if (root is not null) 1 process(root) 2 preOrder(root- >leftSubtree) 3 preOrder(root- >rightSubtree) 2 return
แบบ Inorder algorithm inOrder (val root <node pointer>) L N R algorithm inOrder (val root <node pointer>) 1 if (root is not null) 1 inOrder(root- >leftSubtree) 2 process(root) 3 inOrder(root- >rightSubtree) 2 return
แบบ Postorder algorithm postOrder (val root <node pointer>) L R N algorithm postOrder (val root <node pointer>) 1 if (root is not null) 1 postOrder(root- >leftSubtree) 2 postOrder(root- >rightSubtree) 3 process(root) 2 return
Breath-first algorithm breathFirst (val root <node pointer>) 1 p = root 2 while (p not null) 1 process(p) 2 if (p->left not null) 1 enqueue(p->left) 3 if (p->right not null) 1 enqueue(p->right) 4 if (not emptyQueue) 1 dequeue(p) else 1 p = null 3 return
Binary Tree Application Expression Tree Huffman Code Binary Search Tree
Expression Tree หมายถึง Binary Tree ที่มีคุณสมบัติดังต่อไปนี้ 1. Leaf เก็บ Operand 2 Root และ Internal node เก็บ Operator 3. Subtree เป็น Sub expression
ตัวอย่าง
การท่องใน Expression Tree 1. Preorder Traversal 2. Postorder Traversal 3. Inorder Traversal Prefix Expression Postfix Expression Infix Expression
Preorder Traversal 1 if (root is not null) 1 print(root->token) 2 prefix(root- >leftSubtree) 3 prefix(root- >rightSubtree) 2 return + * a + b c d
Postorder Traversal 1 if (root is not null) 1 postfix(root- >leftSubtree) 2 postfix(root- >rightSubtree) 3 print(root->token) 2 return a b c + * d +
Inorder Traversal 1 if (root is not null) 1 if root->token is operand 1 print(root->token) else 1 print(open parenthesis) 2 infix(root- >leftSubtree) 3 print(root- >token) 4 infix(root- >rightSubtree) 5 print(close parenthesis) 2 return ( ( a * ( b + c ) ) + d )
การสร้าง Expression Tree จาก Postfix Expression พิจารณาทีละ Token จนหมด ถ้า Token เป็น Operand สร้าง Node แล้ว Push ลง Stack ถ้า Token เป็น Operator Pop ขึ้นมา 2 ตัวเชื่อมเป็น Tree โดยใช้ Operator แล้ว Push ลง Stack
( A + B ) * C ( 12 / 3 ) + ( 4 * ( 5 – 2 ) ) 12 3 / + 4 * 5 2 - A B +
expression tree Vs Traversal นิพจน์ทางคณิตศาสตร์ สามารถเขียนได้ 3 รูปแบบ คือ infix , prefix , postfix เช่น (a + b) * c มี infix prefix postfix ซึ่งถ้าเราเปรียบเทียบกับ expression tree จะพบว่า inorder traversal (LNR) preorder traversal (NLR) postorder traversal (LRN) a b + c * (a + b) * c *+abc ab+c* (a + b) * c *+abc ab+c* infix prefix postfix
สร้างนิพจน์ prefix จาก expression tree algorithm prefix if (root is not null) print(root) prefix(root->leftSubtree) prefix(root->rightSubtree) return + * a + b c d
สร้างนิพจน์ postfix จาก expression tree algorithm postfix if (root is not null) postfix(root->leftSubtree) postfix(root->rightSubtree) print(root) return a b c + * d +
สร้างนิพจน์ infix จาก expression tree algorithm infix if (root is not null) if root is operand print(root) else print(open parenthesis) infix(root->leftSubtree) infix(root->rightSubtree) print(close parenthesis) return ( ( a * ( b + c ) ) + d )
สร้าง expression tree จากนิพจน์ postfix อ่านนิพจน์เข้ามาทีละตัวอักษร ถ้าข้อมูลที่อ่านเข้ามาเป็น operand สร้าง tree ใหม่จากข้อมูลที่อ่านเข้ามา (เป็น tree ที่มีแค่โหนดเดียว) push ลง stack ถ้าข้อมูลที่อ่านเข้ามาเป็น operator pop ขึ้นมา 2 tree เชื่อมเป็น tree ใหม่โดยใช้ operator ที่อ่านเข้ามาเป็น root
a b c + * d + initial read a read b stack a stack b a stack
a b c + * d + read c read + read * stack a b a stack stack c b c + b c
a b c + * d + read d read + stack b c + a * stack เมื่อหมดข้อมูล จะได้ผลลัพธ์ว่า tree ที่อยู่ในสแตกคือ expression tree d d + b c a *
General Tree หมายถึง Tree ที่สามารถมี Outdegree ได้ไม่ จำกัดจำนวน
การแปลง General Tree เป็น Binary Tree มี 3 ขั้นตอน ดังนี้ 1. ระบุ Child ที่อยู่ทางซ้ายสุด 2. เชื่อม Sibling เข้าด้วยกัน 3. ลบ Branch ที่ไม่ต้องการ
ตัวอย่าง การแปลง General Tree เป็น Binary Tree
Binary Search Tree :BST นำเอา Binary Tree มาประยุกต์ใช้เพื่อค้นหา ข้อมูล มีคุณสมบัติดังต่อไปนี้ ทุกๆ โหนดในซับทรีด้านซ้ายจะต้องมีค่าน้อย กว่ารูทโหนด ทุกๆ โหนดในซับทรีด้านขวาจะต้องมีค่า มากกว่ารูทโหนด แต่ละซับทรีจะต้องเป็นไบนารีเสิร์ซทรี
Binary Search Tree :BST (1) K All<K All>K
ตัวอย่าง Binary Search Tree 17 17 6 19 17 17 17 6 6 19 19 3 3 14 22
การท่องไปใน BST 23 18 44 12 20 35 52 Preorder Postorder Inorder
การค้นหาโหนดที่มีค่าต่ำที่สุด หาโหนดที่อยู่ด้านซ้ายสุดให้เจอ Algorithm findSmallestBST(root) 1 if (left subtree empty) 1 return (root) 2 end if 3 return findSmallestBST(left subtree) end findSmallestBST
การค้นหาโหนดที่มีค่าสูงที่สุด หาโหนดที่อยู่ด้านขวาสุดให้เจอ Algorithm findLargestBST(root) 1 if (right subtree empty) 1 return (root) 2 end if 3 return findSmallestBST(right subtree) end findSmallestBST
END!