Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

180 行
4.2KB

  1. #include<set>
  2. #include<iostream>
  3. #include<vector>
  4. #include<cassert>
  5. using namespace std;
  6. const int m = 2; // B-tree of order m
  7. const int a = m; // minimal number of keys
  8. const int b = 2*m; // maximal number of keys
  9. template<class T>
  10. struct Node {
  11. // data
  12. vector<T> keys;
  13. vector<Node *> children;
  14. Node* parent;
  15. // interface
  16. Node (Node* p) {parent = p;}
  17. bool is_leaf() {return children.size()==0;}
  18. Node* root () { return (parent==0) ? this : parent->root(); }
  19. Node* find_node (T item);
  20. int find_pos (T item);
  21. bool equals_item (int pos, T item);
  22. } ;
  23. // finds first position i such that keys[i]>=item
  24. template<class T>
  25. int Node<T>::find_pos (T item)
  26. {
  27. int i = 0;
  28. while ((i<keys.size())&&(keys[i]<item)) i++;
  29. return i;
  30. }
  31. // checks if the key at position pos contains item
  32. template<class T>
  33. bool Node<T>::equals_item (int pos, T item) {
  34. return (pos<keys.size()) && !(item<keys[pos]);
  35. }
  36. // finds the node in which the item should be stored
  37. template<class T>
  38. Node<T>* Node<T>::find_node (T item) {
  39. if (is_leaf()) return this;
  40. int pos = find_pos(item);
  41. if (equals_item(pos, item))
  42. return this;
  43. else
  44. return children[pos]->find_node(item);
  45. }
  46. template<class VEC>
  47. VEC subseq (VEC vec, int start, int end)
  48. {
  49. int size = (vec.size()==0) ? 0 : end-start;
  50. VEC result(size);
  51. for (int i = 0; i<size; i++)
  52. result[i] = vec[i+start];
  53. return result;
  54. }
  55. // if necessary, split the node. Returns 0 or a new root
  56. template<class T>
  57. Node<T>* balance (Node<T>* node)
  58. {
  59. int n = node->keys.size();
  60. if (n<=b) return 0;
  61. T median = node->keys[a];
  62. // create a new node
  63. Node<T>* node2 = new Node<T>(node->parent);
  64. node2->keys = subseq(node->keys, a+1,
  65. node->keys.size());
  66. node2->children = subseq(node->children, a+1,
  67. node->children.size());
  68. for (int i=0; i<node2->children.size(); i++)
  69. node2->children[i]->parent = node2;
  70. // handle node
  71. node->keys = subseq(node->keys, 0, a);
  72. node->children = subseq(node->children, 0, a+1);
  73. Node<T>* parent = node->parent;
  74. if (parent==0) // split the root!
  75. {
  76. Node<T>* root = new Node<T>(0);
  77. root->keys.push_back(median);
  78. root->children.push_back(node);
  79. root->children.push_back(node2);
  80. node->parent = root;
  81. node2->parent = root;
  82. return root;
  83. }
  84. // otherwise: insert in parent
  85. int pos=0;
  86. while (parent->children[pos]!=node) pos++;
  87. parent->keys.insert(parent->keys.begin()+pos, median);
  88. parent->children.insert(parent->children.begin()+pos+1, node2);
  89. // recursive call;
  90. return balance(parent);
  91. }
  92. template<class T>
  93. void show (Node<T> *node)
  94. {
  95. cout << node << ": ";
  96. if (node->children.size()>0)
  97. {
  98. cout << node->children[0];
  99. for (int i=0; i<node->keys.size(); i++)
  100. cout << " |" << node->keys[i] << "| "
  101. << node->children[i+1];
  102. }
  103. else
  104. for (int i=0; i<node->keys.size(); i++)
  105. cout << node->keys[i] << " ";
  106. cout << endl;
  107. for (int i=0; i<node->children.size(); i++)
  108. show(node->children[i]);
  109. }
  110. // we could work with a root pointer, but for later use it is
  111. // better to wrap it into a class
  112. template<class T>
  113. class abTree {
  114. public:
  115. abTree () {root = new Node<T>(0);}
  116. void insert (T item);
  117. bool find (T item);
  118. void show () { ::show(root); }
  119. private:
  120. Node<T> *root;
  121. };
  122. template<class T>
  123. void abTree<T>::insert (T item) {
  124. Node<T>* node = root->find_node(item);
  125. int i=node->find_pos(item);
  126. if (node->equals_item(i,item))
  127. node->keys[i] = item;
  128. else
  129. {
  130. node->keys.insert(node->keys.begin()+i, item);
  131. Node<T>* new_root = balance(node);
  132. if (new_root) root = new_root;
  133. }
  134. }
  135. template<class T>
  136. bool abTree<T>::find (T item) {
  137. Node<T>* node = root->find_node(item);
  138. int i=node->find_pos(item);
  139. return node->equals_item(i, item);
  140. }
  141. int main ()
  142. {
  143. abTree<int> tree;
  144. // insertion demo
  145. for (int i=0; i<5; i++) {
  146. tree.insert(i);
  147. tree.show();
  148. }
  149. // testing insertion and retrieval
  150. int n = 10;
  151. for (int i=0; i<n; i++)
  152. tree.insert(i*i);
  153. cout << endl;
  154. tree.show();
  155. for (int i=0; i<2*n; i++)
  156. cout << i << " " << tree.find(i) << endl;
  157. // performance test
  158. //abTree<int> set;
  159. set<int> set; // should be faster
  160. int nn = 1000000;
  161. for (int i=0; i<nn; i++)
  162. set.insert(i*i);
  163. for (int i=0; i<nn; i++)
  164. set.find(i*i);
  165. }