SplayTree-private-inl.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. //static int global_height;
  2. template <typename K, typename V>
  3. SplayTreeNode<K,V>*
  4. SplayTree<K,V>::insertInSubtree(SplayTreeNode<K,V>* current, K key, V value) {
  5. if (current == NULL){
  6. size++;
  7. return new SplayTreeNode<K, V>(key, value);
  8. }
  9. else if (key == current->key){
  10. throw std::runtime_error("SplayTree::insertInSubtree" \
  11. "called on key already in tree.");
  12. }
  13. else if (key < current->key){
  14. if(current->left != NULL) {
  15. current->left = insertInSubtree(current->left, key, value);
  16. }
  17. else {
  18. current->left = new SplayTreeNode<K, V>(key, value);
  19. current->left->parent = current;
  20. size++;
  21. }
  22. return splay(current);
  23. }
  24. else if (key > current->key){
  25. if(current->right != NULL) {
  26. current->right = insertInSubtree(current->right, key, value);
  27. }
  28. else {
  29. current->right = new SplayTreeNode<K, V>(key, value);
  30. current->right->parent = current;
  31. size++;
  32. }
  33. return splay(current);
  34. }
  35. }
  36. /**
  37. * This recursive helper function updates key-value pair in the subtree
  38. * of the tree, or throws a runtime_error if the key is not present.
  39. */
  40. template <typename K, typename V>
  41. void SplayTree<K,V>::updateInSubtree(SplayTreeNode<K,V>* current, K key, V value) {
  42. if (current == NULL){
  43. throw std::runtime_error("Key not found in SplayTree::updateInSubtree.");
  44. }
  45. else if (key == current->key){
  46. current->value = value;
  47. }
  48. else if (key < current->key){
  49. updateInSubtree(current->left, key, value);
  50. }
  51. else if (key > current->key){
  52. updateInSubtree(current->right, key, value);
  53. }
  54. return;
  55. }
  56. /**
  57. * This recursive helper function removes a key-value pair from a subtree
  58. * of the tree, or throws a runtime_error if that key was not present.
  59. *
  60. * It returns a pointer to the root of the subtree. This root is often
  61. * the node that was passed as an argument to the function (current) but
  62. * might be a different node if current contains the key we are removing
  63. * from the tree.
  64. */
  65. template <typename K, typename V>
  66. SplayTreeNode<K,V>*
  67. SplayTree<K,V>::removeFromSubtree(SplayTreeNode<K,V>* current,
  68. K key) {
  69. if (current == NULL) {
  70. throw std::runtime_error("SplayTree::remove called on key not in tree.");
  71. }
  72. else if (key == current->key) { // We've found the node to remove
  73. if ((current->left == NULL) && (current->right == NULL)) {
  74. size--;
  75. delete current;
  76. return NULL;
  77. }
  78. else if (current->left == NULL) {
  79. SplayTreeNode<K,V>* tempNode = current->right;
  80. delete current;
  81. size--;
  82. return balance(tempNode);
  83. }
  84. else if (current->right == NULL) {
  85. SplayTreeNode<K,V>* tempNode = current->left;
  86. delete current;
  87. size--;
  88. return balance(tempNode);
  89. }
  90. else {
  91. SplayTreeNode<K,V>* minimum = current->right;
  92. while (minimum->left != NULL) {
  93. minimum = minimum->left;
  94. }
  95. current->key = minimum->key;
  96. current->value = minimum->value;
  97. current->right = removeFromSubtree(current->right, current->key);
  98. }
  99. }
  100. else if (key < current->key) {
  101. current->left = removeFromSubtree(current->left, key);
  102. }
  103. else {
  104. current->right = removeFromSubtree(current->right, key);
  105. }
  106. return balance(current);
  107. }
  108. /**
  109. * Returns true if a key is contained in a subtree of the tree, and
  110. * false otherwise.
  111. */
  112. template <typename K, typename V>
  113. bool SplayTree<K,V>::containsInSubtree(SplayTreeNode<K,V>* current, K key) {
  114. if (current == NULL){
  115. return false;
  116. }
  117. else if (key == current->key){
  118. splay(current);
  119. return true;
  120. }
  121. else if (key < current->key){
  122. return containsInSubtree(current->left, key);
  123. }
  124. else {
  125. return containsInSubtree(current->right, key);
  126. }
  127. }
  128. /**
  129. * Given a key, returns the value for that key from a subtree of the tree.
  130. * Throws a runtime_error if the key is not in the subtree.
  131. */
  132. template <typename K, typename V>
  133. V SplayTree<K,V>::findInSubtree(SplayTreeNode<K,V>* current, K key) {
  134. if (current == NULL) {
  135. throw std::runtime_error("LinkedBS::findInSubtree called on an empty tree");
  136. }
  137. else if (key == current->key) {
  138. current = splay(current);
  139. return current->value;
  140. }
  141. else if (key < current->key) {
  142. return findInSubtree(current->left, key);
  143. }
  144. else {
  145. return findInSubtree(current->right, key);
  146. }
  147. }
  148. /**
  149. * Returns the largest key in a subtree of the tree.
  150. */
  151. template <typename K, typename V>
  152. K SplayTree<K,V>::getMaxInSubtree(SplayTreeNode<K,V>* current) {
  153. if (current->right == NULL) {
  154. return current->key;
  155. }
  156. return getMaxInSubtree(current->right);
  157. }
  158. /**
  159. * Returns the smallest key in a subtree of the tree.
  160. */
  161. template <typename K, typename V>
  162. K SplayTree<K,V>::getMinInSubtree(SplayTreeNode<K,V>* current) {
  163. if (current->left == NULL) {
  164. return current->key;
  165. }
  166. return getMinInSubtree(current->left);
  167. }
  168. /*
  169. * Returns the height of a subtree of the tree, or -1 if the subtree
  170. * is empty.
  171. *
  172. template <typename K, typename V>
  173. int SplayTree<K,V>::getHeightOfSubtree(SplayTreeNode<K,V>* current) {
  174. if (current == NULL) {
  175. return -1;
  176. }
  177. int l = getHeightOfSubtree(current->left);
  178. int r = getHeightOfSubtree(current->right);
  179. if (l >= r) {
  180. return ++l;
  181. }
  182. else
  183. return ++r;
  184. }
  185. */
  186. /**
  187. * Recursively builds a post-order iterator for a subtree of the tree.
  188. */
  189. template <typename K, typename V>
  190. void SplayTree<K,V>::buildPostOrder(SplayTreeNode<K,V>* current,
  191. Queue< Pair<K,V> >* it) {
  192. if (current == NULL) {
  193. return;
  194. }
  195. buildPostOrder(current->left, it);
  196. buildPostOrder(current->right, it);
  197. it->enqueue( Pair<K,V>(current->key, current->value) );
  198. }
  199. /**
  200. * Recursively builds a pre-order iterator for a subtree of the tree.
  201. */
  202. template <typename K, typename V>
  203. void SplayTree<K,V>::buildPreOrder(SplayTreeNode<K,V>* current,
  204. Queue< Pair<K,V> >* it) {
  205. if (current == NULL){
  206. return;
  207. }
  208. it->enqueue( Pair<K,V>(current->key, current->value) );
  209. buildPreOrder(current->left, it);
  210. buildPreOrder(current->right, it);
  211. }
  212. /**
  213. * Recursively builds an in-order iterator for a subtree of the tree.
  214. */
  215. template <typename K, typename V>
  216. void SplayTree<K,V>::buildInOrder(SplayTreeNode<K,V>* current,
  217. Queue< Pair<K,V> >* it) {
  218. if (current == NULL){
  219. return;
  220. }
  221. buildInOrder(current->left, it);
  222. it->enqueue( Pair<K,V>(current->key, current->value) );
  223. buildInOrder(current->right, it);
  224. }
  225. /**
  226. * Performs a post-order traversal of the tree, deleting each node from the
  227. * heap after we have already traversed its children.
  228. */
  229. template <typename K, typename V>
  230. void SplayTree<K,V>::traverseAndDelete(SplayTreeNode<K,V>* current) {
  231. if (current == NULL) {
  232. return; //nothing to delete
  233. }
  234. traverseAndDelete(current->left);
  235. traverseAndDelete(current->right);
  236. delete current;
  237. }
  238. template <typename K, typename V>
  239. SplayTreeNode<K,V>* SplayTree<K,V>::balance(SplayTreeNode<K,V>* current) {
  240. //check height to see if stop with AVL (note we need to think about global_height)
  241. if (current->height > 0) {
  242. /*do AVL balance, but we will implement this once SplayTree is working
  243. well. Also remember to add the balance functions from AVLTree.h
  244. */
  245. return current;
  246. }
  247. else{
  248. return current;
  249. }
  250. }
  251. template <typename K, typename V>
  252. SplayTreeNode<K,V>* SplayTree<K,V>::splay(SplayTreeNode<K,V>* current) {
  253. //consider adding computeHeightFromChildren here for AVL
  254. //finished splay, return this node to obtain value
  255. if (current->parent == NULL){
  256. return current;
  257. }
  258. else if (current->parent->parent == NULL) {
  259. if (current == current->parent->left){
  260. zigRight(current);
  261. return current;
  262. }
  263. else {
  264. zigLeft(current);
  265. return(current);
  266. }
  267. }
  268. else {
  269. SplayTreeNode<K,V>* gParent = current->parent->parent;
  270. SplayTreeNode<K,V>* gPP = gParent->parent;
  271. if (current == current->parent->left) {
  272. if (current->parent == gParent->left) {
  273. if(gPP == NULL) {
  274. zig_zigLeft(current);
  275. }
  276. else {
  277. if (gPP->key > current->key) {
  278. gPP->left = zig_zigLeft(current);
  279. }
  280. else {
  281. gPP->right = zig_zigLeft(current);
  282. }
  283. }
  284. }
  285. else {
  286. if(gPP == NULL) {
  287. zig_zagLeft(current);
  288. }
  289. else {
  290. if (gPP->key > current->key) {
  291. gPP->left = zig_zagLeft(current);
  292. }
  293. else {
  294. gPP->right = zig_zagLeft(current);
  295. }
  296. }
  297. }
  298. splay(current);
  299. }
  300. else {
  301. if (current->parent == gParent->right) {
  302. if(gPP == NULL) {
  303. zig_zigRight(current);
  304. }
  305. else {
  306. if (gPP->key > current->key) {
  307. gPP->left = zig_zigRight(current);
  308. }
  309. else {
  310. gPP->right = zig_zigRight(current);
  311. }
  312. }
  313. }
  314. else {
  315. if(gPP == NULL) {
  316. zig_zigRight(current);
  317. }
  318. else {
  319. if (gPP->key > current->key) {
  320. gPP->left = zig_zagRight(current);
  321. }
  322. else {
  323. gPP->right = zig_zagRight(current);
  324. }
  325. }
  326. }
  327. splay(current);
  328. }
  329. return current;
  330. }
  331. }
  332. template <typename K, typename V>
  333. SplayTreeNode<K,V>* SplayTree<K,V>::zigLeft(SplayTreeNode<K,V>* current) {
  334. //making the assumption that we know current is left child
  335. SplayTreeNode<K,V> * P = current->parent;
  336. P->left = current->right;
  337. P->left->parent = P;
  338. current->right = P;
  339. current->parent = P->parent;
  340. P->parent = current;
  341. //premptively added these calls here for AVL section
  342. //computeHeightFromChildren(current);
  343. //computeHeightFromChildren(P);
  344. return current;
  345. }
  346. template <typename K, typename V>
  347. SplayTreeNode<K,V>* SplayTree<K,V>::zigRight(SplayTreeNode<K,V>* current) {
  348. SplayTreeNode<K,V> * P = current->parent;
  349. P->right = current->left;
  350. P->right->parent = P;
  351. current->left = P;
  352. current->parent = P->parent;
  353. P->parent = current;
  354. //premptively added these calls here for AVL section
  355. //computeHeightFromChildren(current);
  356. //computeHeightFromChildren(P);
  357. return current;
  358. }
  359. /* for all four we zig from the bottom, then zig from the top */
  360. template <typename K, typename V>
  361. SplayTreeNode<K,V>* SplayTree<K,V>::zig_zigLeft(SplayTreeNode<K,V>* current) {
  362. SplayTreeNode<K,V> * gParent = current->parent->parent;
  363. gParent->left = zigLeft(current);
  364. return zigLeft(current);
  365. }
  366. template <typename K, typename V>
  367. SplayTreeNode<K,V>* SplayTree<K,V>::zig_zigRight(SplayTreeNode<K,V>* current) {
  368. SplayTreeNode<K,V> * gParent = current->parent->parent;
  369. gParent->right = zigRight(current);
  370. return zigRight(current);
  371. }
  372. template <typename K, typename V>
  373. SplayTreeNode<K,V>* SplayTree<K,V>::zig_zagLeft(SplayTreeNode<K,V>* current) {
  374. SplayTreeNode<K,V> * gParent = current->parent->parent;
  375. gParent->left = zigRight(current);
  376. gParent->right->parent = gParent;
  377. return zigLeft(current);
  378. }
  379. template <typename K, typename V>
  380. SplayTreeNode<K,V>* SplayTree<K,V>::zig_zagRight(SplayTreeNode<K,V>* current) {
  381. SplayTreeNode<K,V> * gParent = current->parent->parent;
  382. gParent->right = zigLeft(current);
  383. return zigRight(current);
  384. }