1 / 53

Chapter 10

Chapter 10. Multiway Trees. An m -way tree is a search tree where nodes can have 0 to m (where m = order) sub-trees A Binary Search Tree is an m -way tree of order 2 Properties: Each node has 0 to m sub-trees

darren
Télécharger la présentation

Chapter 10

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. Chapter 10 Multiway Trees

  2. An m-way tree is a search tree where nodes can have 0 to m (where m = order) sub-trees A Binary Search Tree is an m-way tree of order 2 Properties: Each node has 0 to m sub-trees A node with k < m sub-trees contains k sub-tree pointers, some of which may be null, and k – 1 data entries Key values in first sub-tree are all less than key value in the first entry; key values in other sub-trees are all greater than or equal to key value in their parent entry Keys of data entries are ordered key1 <= key2 <= ... <=keyk All sub-trees are themselves multi-way trees m-way trees

  3. Figure 10-1 m-way tree of order 4

  4. There is always one more pointer than there are entries in each node First pointer identifies all sub-trees that contain keys less than first entry in the node An entry count field tracks number of entries in each node Each entry has a data field and a pointer to its right sub-tree, that has keys greater than or equal to the entry Observations

  5. Figure 10-2 A four-way tree

  6. Figure 10-3 m-way node structure

  7. A B-tree is an m-way search tree with these additional properties: The root is either a leaf or it has 2...m sub-trees All internal nodes have at least upper limit of [m/2] non-null sub-trees and at most m non-null sub-trees All leaf nodes are at the same level (perfectly balanced) A leaf node has at least upper limit of [m/2] - 1 and at most m - 1 entries A B-tree is a perfectly balanced m-way tree where each node (with exception of root) is at least half full B-Trees

  8. Figure 10-4 A B-tree of order 5

  9. Insertions take place at a leaf node, after a searching for the correct insert location A B-Tree grows from the bottom up (from leaves to root) An overfull occurs when a leaf node is full; this requires node to be split into two nodes: New memory is allocated for a parent node Half of the node values are split on the left, and half on the right (this excludes median value node) The node with the median value will become the parent B-Tree Insertion

  10. Figure 10-5 B-tree insert overview

  11. Figure 10-9 (a, b, and c) Build a B-tree of order 5

  12. Figure 10-9 (d, e, and f) Build a B-tree of order 5

  13. Figure 10-6 B-tree insert design

  14. algorithm BTreeInsert (ref tree <pointer>, val data <record>) if (tree null) Empty tree. Insert first node. allocate (newPtr) if (allocate successful) newPtr->firstPtr = null newPtr->numEntries = 1 newPtr->entries[0].data = dataIn newPtr->entries[0].rightPtr = null tree = newPtr return true else abort program (Out of memory) end if end if taller = insertNode (tree, data, upEntry) Algorithm 10-1 B-tree insert

  15. if (taller true) Tree has grown. Create new root allocate (newPtr) if (allocate successful) newPtr->entries[0] = upEntry newPtr->firstPtr = tree newPtr->numEntries = 1 tree = newPtr else abort program (Out of Memory) endif end if return end BTreeInsert Algorithm 10-1 B-tree insert (Cont'd)

  16. algorithm insertNode (ref root <pointer>, val dataIn <data type>, ref upEntry <entry>) if (root null) upEntry.data = dataIn upEntry.rightPtr = null taller = true return taller end if entryNdx = searchNode (root, data.key) newEntryLow = dataIn.key < root->entries[entryNdx].data.key if (entryNdx equal 0 and newEntryLow) subTree = root->firstPtr else subTree = root->entries[entryNdx].rightPtr endif Algorithm 10-2 B-tree insert node

  17. taller = insertNode (subTree, data, upEntry) if (taller) if (node full) splitNode (root, entryNdx, newEntryLow, upEntry) taller = true else if (newEntryLow) insertEntry (root, entryNdx, upEntry) else insertEntry (root, entryNdx + 1, upEntry) end if root->numEntries = root->numEntries + 1 taller = false end if end if return taller end insertNode Algorithm 10-2 B-tree insert node (cont'd)

  18. Figure 10-7 Build B-tree, first overflow 3 4 7 minEntries = 2 entryNdx = 0 newEntryLow = false root = {21, 57, 78} subTree = {42, 45, 63, 74} 0 entryNdx = 1 newEntryLow = false root = {42, 45, 63, 74} subTree = Null (rightPtr of 45) fromNdx = 2 toNdx = 2 splitNode(root, 1, false, upEntry) 1 entryNdx = 1 root = Null taller = true dataIn = 57 1

  19. algorithm searchNode (val nodePtr <pointer>, val target <key>) if (target < nodePtr->entry[0].data.key) walker = 0 else Sequential searching from end to beginning walker = nodePtr->numEntries – 1 loop (walker > 0 AND target < nodePtr->entries[walker].data.key) walker = walker – 1 end loop end if return walker end searchNode Algorithm 10-3 B-tree search node

  20. algorithm splitNode (ref node <pointer>, val entryNdx <index>, val newEntryLow <Boolean>, ref upEntry <entry>) minEntries = minimum number of entries allocate (rightPtr) Build right subtree node if (entryNdx < minEntries) fromNdx = minEntries else fromNdx = minEntries + 1 end if toNdx = 0 rightPtr->numEntries = node->numEntries – fromNdx loop (fromNdx < node->numEntries) rightPtr->entries[toNdex] = node->entries[fromNdx] toNdx = toNdx + 1 fromNdx = fromNdx + 1 end loop node->numEntries = node->numEntries – rightPtr->numEntries Algorithm 10-4 B-tree split node

  21. if (entryNdx < minEntries) Insert in original (lower) node if (newEntryLow) insertEntry (node, entryNdx, upEntry) else insertEntry (node, entryNdx + 1, upEntry) end if else Insert in new (right node) insertEntry(rightPtr, entryNdx – minEntries, upEntry) rightPtr->numEntries = rightPtr->numEntries + 1 node->numEntries = node->numEntries – 1 Build entry for parent end if upEntry.data = node->entries[minEntries].data upEntry.rightPtr = rightPtr rightPtr->firstPtr = node->entries[minEntries].rightPtr return end splitNode Algorithm 10-4 B-tree split node (Cont'd)

  22. Figure 10-8 Split node B-tree order of 5 a) New entry <= median 2 2 2 2 2 2 ≤

  23. Figure 10-8 Split node B-tree order of 5 b) New entry > median 3 3 2 3 3 2 3 3 2 3

  24. algorithm insertEntry (val node <pointer>, val insertNdx <key>, val newEntry <entry>) shifter = node->numEntries loop (shifter > insertNdx) node->entries[shifter] = node->entries[shifter - 1] shifter = shifter -1 end loop node->entries[shifter] = newEntry return end insertEntry Algorithm 10-5 B-tree insert entry

  25. Figure 10-10 B-tree delete design

  26. algorithm BTreeDelete (ref tree <pointer>, val dltKey <key>) if (tree empty) return false end if delete (tree, dltKey, success) if (success) if (tree->numEntries is zero) Tree is shorter -- delete root dltPtr = tree tree = tree->firstPtr recycle (dltPtr) end if end if return success end BTreeDelete Algorithm 10-6 B-tree delete

  27. algorithm delete (ref root <pointer>, val deleteKey <key>, ref success <Boolean>) if (root null) Leaf node found – deleteKey key does not exist return false end if entryNdx = searchNode (root, deleteKey) if (deleteKey equal root->entries[entryNdx].data.key) Found entry to be deleted success = true if (root->entries[entryNdx].rightPtr is null) Entry is a leaf node underflow = deleteEntry (root, entryNdx) else Entry is in internal node if (entryNdx > 0) leftPtr = root->entries[entryNdx – 1].rightPtr else leftPtr = root->firstPtr end if underflow = deleteMid (root, entryNdx, leftPtr) if (underflow) underflow = reFlow (root, entryNdx) end if end if Algorithm 10-7 B-tree node delete

  28. else if (deleteKey < root->entries[0].data.key) deleteKey less than first entry subtree = root->firstPtr else deleteKey is in right subtree subtree = root->entries[entryNdx].rightPtr end if underflow = delete (subtree, deleteKey, success) if (underflow) underflow = reFlow (root, entryNdx) end if end if return underflow end delete Algorithm 10-7 B-tree node delete (cont'd)

  29. algorithm deleteEntry (ref node <pointer>, val entryNdx <key>) shifter = entryNdx + 1 loop (shifter <= node->numEntries) node->entries[shifter - 1] = node->entries[shifter] shifter = shifter + 1 end loop node->numEntries = node->numEntries - 1 if (node->numEntries < minimum entries return true else return false end if end deleteEntry Algorithm 10-8 B-tree delete entry

  30. algorithm deleteMid (ref root <pointer>, val entryNdx <index>, val subtree <pointer>) if (subtree->firstPtr null) Leaf located. Exchange data and delete leaf entry deleteNdx = subtree->numEntries – 1 root->entries[entryNdx].data = subtree->entries[deleteNdx].data deleteNdx = subtree->numEntries - 1 subtree->entries[deleteNdx].data subtree->numEntries = subtree->numEntries – 1 underflow = subtree->numEntries < minimum entries else Not located. Traverse right to locate predecessor right = subtree->numEntries – 1 underflow = deleteMid (root, entryNdx, subtree-> entries[right].rightPtr) if (underflow) underflow = reFlow (subtree, rightNdx) end if end if return underflow end deleteMid Algorithm 10-9 B-tree delete mid

  31. Figure 10-11 B-tree deletions 3 4 • 1 dltPtr = tree • 2 tree = tree->firstPtr • 3 recycle(dltPtr) • 5 end if • 6 return success 0 1 1

  32. algorithm reFlow (ref root <pointer>, val entryNdx <index>) Try to borrow first. Located subtree with available entry. if (entryNdx equal 0) leftTree = root->firstPtr else leftTree = root->entries[entryNdx – 1].rightPtr end if rightTree = root->entries[entryNdx].rightPtr if (rightTree->numEntries > minimum entries) borrowRight (root, entryNdx, leftTree, rightTree) underflow = false Algorithm 10-10 B-tree underflow reFlow

  33. else Can't balance from right. Try left if (leftTree->numEntries > minimum entrees) borrowLeft (root, entryNdx, leftTree, rightTree) underflow = false else Can't borrow. Must combine entries combine (root, entryNdx, leftTree, rightTree) if (root->numEntries < minimum entries) underflow = true else underflow = false end if end if end if return underflow end reFlow Algorithm 10-10 B-tree underflow reFlow (cont'd)

  34. Figure 10-12 Restore order by borrowing

  35. algorithm borrowLeft (ref root <pointer>, val entryNdx <key>, val left <pointer>, val right <pointer>) Shift entries right to make room for new data shifter = right>numEntries loop (shifter > 0) right->entries[shifter] = right->entries[shifter - 1] shifter = shifter -1 end loop Move parent data down and reset right pointer right->entries[0].data = root->entries[entryNdx].data right->entries[0].rightPtr = right->firstPtr Moved entry's rightPtr becomes right tree first pointer fromNdx = left->numEntries – 1 right->firstPtr = left->entries[fromNdx].rightPtr right->numEntries = right->numEntries + 1 Move data from left to parent root->entries[entryNdx].data = left->entries[fromNdx].data left->numEntries = left->numEntries - 1 return end borrowLeft Algorithm 10-11 B-tree borrow left

  36. algorithm borrowRight (ref root <pointer>, val entryNdx <key>, val left <pointer>, val right <pointer>) Move parent and subtree pointer to left tree toNdx = left->numEntries left->entries[toNdx].data = root->entries[entryNdx].data left->entries[toNdx].rightPtr = right->firstPtr left->numEntries = left->numEntries + 1 Move right data to parent root->entries[entryNdx].data = right->entries[0].data Set right tree first pointer and shift data right->firstPtr = right->entries[0].rightPtr shifter = 0 loop (shifter < right->numEntries – 1) right->entries[shifter] = right->entries[shifter + 1] shifter = shifter + 1 end loop right->numEntries = right->numEntries - 1 return end borrowRight Algorithm 10-12 B-tree borrow right

  37. Figure 10-13 B-tree delete combine

  38. algorithm combine (ref root <pointer>, val entryNdx <key>, val left <pointer>, val right <pointer>) Move parent and set its rightPtr from right tree toNdx = left->numEntries left->entries[toNdx].data = root->entries[entryNdx].data left->entries[toNdx].rightPtr = right->firstPtr left->numEntries = left->numEntries + 1 root->numEntries = root->numEntries - 1 Move data from right tree to left tree frNdx = 0 toNdx = toNdx + 1 loop (frNdx < right->numEntries) left->entries[toNdx] = right->entries[frNdx] toNdx = toNdx + 1 frNdx = frNdx + 1 end loop left->numEntries = left->numEntries + right->numEntries recycle (right) Now shift data in root to the left shifter = entryNdx loop (shifter < root->numEntries) root->entries[shifter] = root->entries[shifter + 1] shifter = shifter + 1 end loop return end combine Algorithm B-tree combine

  39. Figure 10-14 (a, b, and c) B-tree deletion summary

  40. Figure 10-14 (d and e) B-tree deletion summary

  41. Figure 10-15 Basic B-tree traversal

  42. algorithm BTreeTraversal (val root <pointer>) scanCount = 0 ptr = root->firstPtr loop (scanCount <= root->numEntries) Test for subtree if (ptr not null) BTreeTraversal (ptr) end if Subtree processed –- get next entry if (scanCount < root->numEntries) process (root->entries[scanCount].data ptr = root->entires[scanCount].rightPtr end if scanCount = scanCount + 1 end loop return end insertEntry Algorithm 10-14 B-tree traversal

  43. algorithm BTreeSearch (val root <pointer>, val srchKey <key>, ref node < pointer> ref foundLoc <index>) if (emtpy tree) return false end if if (srchKey < first entry) return BTreeSearch (root->firstPtr, srchKey, node, foundLoc) end if foundLoc = root->numEntries - 1 loop (srchKey < root->entries[foundLoc].data.key) foundLoc = foundLoc - 1 end loop if (srchKey equal root->entries[foundLoc].data.key) node = root return true end if return BTreeSearch (root->entries[foundLoc].rightPtr, srchKey, node, foundLoc) end BTreeSearch Algorithm 10-15 B-tree search

  44. Specialized B-Trees have unique names: 2-3 tree (B-tree of order 3) Each non-root node has two or three sub-trees The root may have zero, two, or three sub-trees 2-3-4 tree (B-tree of order 4) Each node can have two, three, or four children Simplified B-Trees

  45. Figure 10-16 2-3 trees

  46. Figure 10-17 2-3-4 tree

  47. B*Tree When node overflows, data are redistributed among the node's siblings. Splitting occurs only when all siblings are full When nodes are split, data from two full siblings are divided among the two full nodes and a new node: all three nodes are two-thirds full B-Tree Variations

  48. Figure 10-18 B*tree insertion

  49. B+Tree Enables random and sequential data processing Each data entry must be represented at the leaf level. Internal nodes (used for searching) don't contain data Each leaf node contains an extra pointer, used to move to the next leaf node in sequence B-Tree Variations (Cont'd)

  50. Figure 10-19 B+tree

More Related