|
| 1 | +// |
| 2 | +// Created by Jinho on 12/14/2022. |
| 3 | +// |
| 4 | +#include "AVL.h" |
| 5 | + |
| 6 | +Node::Node(int value) { |
| 7 | + data = value; |
| 8 | + leftChild = rightChild = NULL; |
| 9 | + height = 1; |
| 10 | + balanceFactor = 0; |
| 11 | +} |
| 12 | + |
| 13 | +void bstree::visit(Node* ptr) { |
| 14 | + cout << ptr->data << "\t"; |
| 15 | + if (ptr->leftChild) cout << "left : " << ptr->leftChild->data << '\t'; |
| 16 | + else cout << "left : empty\t"; |
| 17 | + if (ptr->rightChild) cout << "right : " << ptr->rightChild->data << '\t'; |
| 18 | + else cout << "right : empty\t"; |
| 19 | + cout << '\n'; |
| 20 | +} |
| 21 | + |
| 22 | +void bstree::show(Node* root) { |
| 23 | + cout << '\n'; |
| 24 | + queue<Node*> bfsQueue; |
| 25 | + bfsQueue.push(root); |
| 26 | + Node *nodeNow; |
| 27 | + while (!bfsQueue.empty()) { |
| 28 | + nodeNow = bfsQueue.front(); |
| 29 | + bfsQueue.pop(); |
| 30 | + visit(nodeNow); |
| 31 | + if (nodeNow->leftChild) bfsQueue.push(nodeNow->leftChild); |
| 32 | + if (nodeNow->rightChild) bfsQueue.push(nodeNow->rightChild); |
| 33 | + } |
| 34 | +} |
| 35 | + |
| 36 | +Node *bstree::insert(const int value, Node *&nodeNow) { |
| 37 | + if (!nodeNow) return nodeNow = new Node(value); |
| 38 | + if (value == nodeNow->data) return nodeNow; |
| 39 | + if (value < nodeNow->data) nodeNow->leftChild = insert(value, nodeNow->leftChild); |
| 40 | + if (value > nodeNow->data) nodeNow->rightChild = insert(value, nodeNow->rightChild); |
| 41 | + |
| 42 | + setBF(nodeNow); |
| 43 | + if (nodeNow->balanceFactor < -1 || nodeNow->balanceFactor > 1) return rotation(nodeNow, value); |
| 44 | + return nodeNow; |
| 45 | +} |
| 46 | + |
| 47 | +bool bstree::search(const int key, Node* root) { |
| 48 | + cout << root->data; |
| 49 | + |
| 50 | + if (root->data == key) { |
| 51 | + cout << '\n'; |
| 52 | + return true; |
| 53 | + } |
| 54 | + |
| 55 | + cout << " -> "; |
| 56 | + |
| 57 | + Node *nodeNext = key <= root->data ? root->leftChild : root->rightChild; |
| 58 | + if (!nodeNext) { |
| 59 | + cout << " X (there is no nodes that has value " << key << ") \n"; |
| 60 | + return false; |
| 61 | + } |
| 62 | + |
| 63 | + return search(key, nodeNext); |
| 64 | +} |
| 65 | + |
| 66 | +Node *bstree::del(const int key, Node* nodeNow) { |
| 67 | + if (!nodeNow) return nodeNow; |
| 68 | + if (key < nodeNow->data) nodeNow->leftChild = del(key, nodeNow->leftChild); |
| 69 | + else if (key > nodeNow->data) nodeNow->rightChild = del(key, nodeNow->rightChild); |
| 70 | + else { |
| 71 | + // find the node |
| 72 | + if (!nodeNow->leftChild && !nodeNow->rightChild) nodeNow = NULL; |
| 73 | + else if (!nodeNow->leftChild) nodeNow = nodeNow->rightChild; |
| 74 | + else if (!nodeNow->rightChild) nodeNow = nodeNow->leftChild; |
| 75 | + else { |
| 76 | + Node *ptr = nodeNow->leftChild; |
| 77 | + while (ptr->rightChild) { |
| 78 | + ptr = ptr->rightChild; |
| 79 | + } |
| 80 | + nodeNow->data = ptr->data; |
| 81 | + del(nodeNow->data, nodeNow->leftChild); |
| 82 | + } |
| 83 | + } |
| 84 | + if (!nodeNow) return nodeNow; |
| 85 | + |
| 86 | + setBF(nodeNow); |
| 87 | + if (nodeNow->balanceFactor < -1 || nodeNow->balanceFactor > 1) return rotation(nodeNow, key); |
| 88 | + return nodeNow; |
| 89 | +} |
| 90 | + |
| 91 | +void bstree::setBF(Node* startNode) { |
| 92 | + int leftHeight, rightHeight; |
| 93 | + leftHeight = startNode->leftChild ? startNode->leftChild->height : 0; |
| 94 | + rightHeight = startNode->rightChild ? startNode->rightChild->height : 0; |
| 95 | + startNode->height = leftHeight < rightHeight ? rightHeight + 1 : leftHeight + 1; |
| 96 | + startNode->balanceFactor = leftHeight - rightHeight; |
| 97 | +} |
| 98 | + |
| 99 | +Node *bstree::rotation(Node* startNode, int value) { |
| 100 | + // 1. LL rotation |
| 101 | + Node *tempNode; |
| 102 | + if (startNode->leftChild && value <= startNode->leftChild->data) { |
| 103 | + tempNode = startNode->leftChild; |
| 104 | + rotation(startNode, startNode->leftChild); |
| 105 | + return tempNode; |
| 106 | + } |
| 107 | + |
| 108 | + // 2. RR rotation |
| 109 | + if (startNode->rightChild && startNode->rightChild->data < value) { |
| 110 | + tempNode = startNode->rightChild; |
| 111 | + rotation(startNode, startNode->rightChild); |
| 112 | + return tempNode; |
| 113 | + } |
| 114 | + |
| 115 | + // 3. LR rotation |
| 116 | + if (value <= startNode->data) { |
| 117 | + tempNode = startNode->leftChild->rightChild; |
| 118 | + rotation(startNode->leftChild, startNode->leftChild->rightChild); |
| 119 | + rotation(startNode, startNode->leftChild); |
| 120 | + } |
| 121 | + |
| 122 | + // 4. RL rotation |
| 123 | + if (startNode->data < value) { |
| 124 | + tempNode = startNode->rightChild->leftChild; |
| 125 | + rotation(startNode->rightChild, startNode->rightChild->leftChild); |
| 126 | + rotation(startNode, startNode->rightChild); |
| 127 | + } |
| 128 | + return tempNode; |
| 129 | +} |
| 130 | + |
| 131 | +void bstree::rotation(Node* start, Node* end) { |
| 132 | + if (start->leftChild == end) { |
| 133 | + start->leftChild = end->rightChild; |
| 134 | + end->rightChild = start; |
| 135 | + } else { |
| 136 | + start->rightChild = end->leftChild; |
| 137 | + end->leftChild = start; |
| 138 | + } |
| 139 | +} |
0 commit comments