No Description

main.cpp 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
  2. #include "catch.hpp"
  3. #include <queue>
  4. #include <iostream>
  5. using namespace std;
  6. class BTNode {
  7. public:
  8. int key;
  9. BTNode *left, *right;
  10. BTNode(int k = 0, BTNode *l = NULL, BTNode *r = NULL) : key(k), left(l), right(r) {}
  11. };
  12. class BST {
  13. private:
  14. BTNode *root;
  15. public:
  16. BST(): root(NULL) {}
  17. void insert(int k);
  18. void insertRec(int k);
  19. void insertRec(int k, BTNode *r);
  20. void remove(int k);
  21. void remove(int k, BTNode *r);
  22. void recDisplay(ostream &out) const;
  23. void recDisplay(ostream &out, BTNode *cur, int dist) const;
  24. BTNode *search(int k) const;
  25. BTNode *searchRec(int k) const;
  26. BTNode *searchRec(int k, BTNode *r) const;
  27. int getHeight() const;
  28. int getHeight(BTNode *r) const;
  29. int sum() const;
  30. int sum(BTNode *r) const;
  31. int leafQty() const;
  32. int leafQty(BTNode *n) const;
  33. int parentsOfTwo() const;
  34. int parentsOfTwo(BTNode *n) const;
  35. string InOrder() const;
  36. void InOrder(BTNode *n, string &st) const;
  37. string BFS() const;
  38. };
  39. // function search:
  40. // Given k, a key to search, returns a pointer to the first
  41. // node that contains such key. If not found returns a NULL pointer.
  42. BTNode* BST::search(int k) const {
  43. BTNode* cur = root;
  44. while (cur) {
  45. if (k == cur->key) {return cur;}
  46. // Found
  47. else if (k < cur->key) { cur = cur->left; }
  48. else { cur = cur->right; }
  49. }
  50. return NULL;
  51. }
  52. // function insert:
  53. // Given k, a key to insert, inserts into the BST.
  54. // In this implementation if the key already exists in the tree
  55. // it will be inserted in the RIGHT subtree of the existing key.
  56. void BST::insert(int k) {
  57. BTNode *cur;
  58. BTNode *n = new BTNode(k);
  59. if (!root) {
  60. // This tree is empty, the new node is the root!
  61. root = n;
  62. }
  63. else {
  64. // Lets search the tree for a place to insert....
  65. cur = root;
  66. while (cur) {
  67. if (k < cur->key){
  68. // The value to insert is less than current node
  69. if (cur->left == NULL) {
  70. // If we have reached a node who lacks a left child
  71. // then our new node will be the left child
  72. cur->left = n;
  73. cur = NULL;
  74. }
  75. else {
  76. // keep looking for a place to insert, on the left subtree
  77. cur = cur->left;
  78. }
  79. }
  80. else {
  81. // The value to insert is greater or equal than current node
  82. if (cur->right == NULL){
  83. // If we have reached a node who lacks a right child
  84. // then our new node will be the right child
  85. cur->right = n;
  86. cur = NULL;
  87. }
  88. else {
  89. // keep looking for a place to insert, on the right subtree
  90. cur = cur->right;
  91. }
  92. }
  93. }
  94. }
  95. }
  96. // functions recDisplay:
  97. // Print the tree to the standard output.
  98. void BST::recDisplay(ostream &out) const {
  99. recDisplay(out, root, 0);
  100. }
  101. void BST::recDisplay(ostream &out, BTNode *cur, int dist) const{
  102. if (cur) {
  103. if (cur->right) recDisplay(out, cur->right, dist + 1);
  104. for (int i = 0; i < dist; i++) cout << " ";
  105. out << cur->key << endl;
  106. if (cur->left) recDisplay(out, cur->left, dist + 1);
  107. }
  108. }
  109. // functions remove:
  110. // Given k, a key to remove, removes the first node that it finds with
  111. // such key.
  112. void BST::remove(int k) {
  113. remove(k, root);
  114. }
  115. void BST::remove(int k, BTNode *r) {
  116. BTNode *parent = NULL;
  117. BTNode *cur = r;
  118. while (cur) { // Search for node
  119. if (cur->key == k) { // Node found
  120. if (cur->left == NULL && cur->right == NULL) { // Remove leaf
  121. cout << "cur is a leaf: " << cur->key << endl;
  122. if (!parent) { // Node is root
  123. root = NULL;
  124. }
  125. else if (parent->left == cur)
  126. parent->left = NULL;
  127. else
  128. parent->right = NULL;
  129. delete cur;
  130. }
  131. else if (cur->left && cur->right == NULL) { // Remove node with only left child
  132. if (!parent) // Node is root
  133. root = cur->left;
  134. else if (parent->left == cur)
  135. parent->left = cur->left;
  136. else
  137. parent->right = cur->left;
  138. delete cur;
  139. }
  140. else if (cur->left == NULL && cur->right) { // Remove node with only right child
  141. if (!parent) // Node is root
  142. root = cur->right;
  143. else if (parent->left == cur)
  144. parent->left = cur->right;
  145. else
  146. parent->right = cur->right;
  147. delete cur;
  148. }
  149. else { // Remove node with two children
  150. // Find successor (leftmost child of right subtree)
  151. BTNode *suc = cur->right;
  152. while (suc->left )
  153. suc = suc->left;
  154. int successorData = suc->key;
  155. remove(suc->key, cur); // Remove successor
  156. cur->key = successorData;
  157. }
  158. return; // Node found and removed
  159. }
  160. else if (cur->key < k) { // Search right
  161. parent = cur;
  162. cur = cur->right;
  163. }
  164. else { // Search left
  165. parent = cur;
  166. cur = cur->left;
  167. }
  168. }
  169. return; // Node not found
  170. }
  171. // function getHeight:
  172. // Returns the height of the tree.
  173. int BST::getHeight() const {
  174. return getHeight(root);
  175. }
  176. int BST::getHeight(BTNode *r) const {
  177. if (!r) return -1;
  178. int leftHeight = getHeight(r->left);
  179. int rightHeight = getHeight(r->right);
  180. return 1 + max(leftHeight, rightHeight);
  181. }
  182. // function sum:
  183. // Returns the sum of all keys in the tree.
  184. int BST::sum() const { return sum(root);}
  185. int BST::sum(BTNode *n) const {
  186. if (!n) return 0;
  187. else return n->key + sum(n->left) + sum(n->right);
  188. }
  189. // function leafQty:
  190. // Returns the number of leaves in the tree.
  191. int BST::leafQty() const { return leafQty(root);}
  192. int BST::leafQty(BTNode *n) const {
  193. if (!n) return 0;
  194. if (n->left == NULL && n->right == NULL) return 1;
  195. else return leafQty(n->left) + leafQty(n->right);
  196. }
  197. // function parentsOfTwo:
  198. // Returns the number of nodes that are parents of two children.
  199. int BST::parentsOfTwo() const {
  200. return parentsOfTwo(root);
  201. }
  202. int BST::parentsOfTwo(BTNode *n) const {
  203. if (!n || (!n->left && !n->right)) return 0;
  204. int resultLeft = parentsOfTwo(n->left);
  205. int resultRight = parentsOfTwo(n->right);
  206. if (n->left && n->right) return 1 + resultLeft + resultRight;
  207. else return resultLeft + resultRight;
  208. }
  209. // function InOrder:
  210. // Will return a string containing the sequence of visited keys
  211. // during an in-order traversal (BFS) of the tree.
  212. string BST::InOrder() const {
  213. string st;
  214. InOrder(root, st);
  215. return st;
  216. }
  217. void BST::InOrder(BTNode *n, string &st) const {
  218. if (n) {
  219. InOrder(n->left, st);
  220. st = st + to_string(n->key) + " ";
  221. InOrder(n->right, st);
  222. }
  223. }
  224. // function BFS:
  225. // Will return a string containing the sequence of visited keys
  226. // during a breadth-first traversal of the tree.
  227. string BST::BFS() const {
  228. string st;
  229. queue<BTNode*> q;
  230. if(root!=NULL) q.push(root);
  231. while(!q.empty()) {
  232. BTNode *f = q.front();
  233. st.append(to_string(f->key));
  234. st.append(" ");
  235. if (f->left != NULL) q.push(f->left);
  236. if (f->right != NULL) q.push(f->right);
  237. q.pop();
  238. }
  239. return st;
  240. }
  241. // function searchRec:
  242. // A recursive version of the search algorithm.
  243. BTNode* BST::searchRec(int k) const { return searchRec(k,root); }
  244. BTNode* BST::searchRec(int k, BTNode *r) const {
  245. if (r) {
  246. if (k == r->key) return r;
  247. else if (k < r->key)
  248. return searchRec(k, r->left);
  249. else
  250. return searchRec(k, r->right);
  251. }
  252. return NULL;
  253. }
  254. // function insertRec:
  255. // A recursive version of the insert algorithm.
  256. void BST::insertRec(int k) {
  257. if (!root) root = new BTNode(k);
  258. else insertRec(k, root);
  259. }
  260. void BST::insertRec(int k, BTNode *r) {
  261. if (k < r->key) {
  262. if (r->left == NULL) r->left = new BTNode(k);
  263. else insertRec(k, r->left);
  264. }
  265. else { // k is greater than r->key
  266. if (r->right == NULL) r->right = new BTNode(k);
  267. else insertRec(k, r->right);
  268. }
  269. }
  270. TEST_CASE( "BST is tested", "[BST]" ) {
  271. vector<int> v = {8, 9, 5, 2, 4, 10, 1};
  272. BST B;
  273. for (auto e: v) B.insert(e);
  274. REQUIRE (B.InOrder() == "1 2 4 5 8 9 10 ");
  275. REQUIRE (B.BFS() == "8 5 9 2 10 1 4 ");
  276. // REQUIRE( infix2Postfix("(3 + 4) * 9") == "3 4 + 9 *" );
  277. // REQUIRE( infix2Postfix("3 + 4 * 9") == "3 4 9 * +" );
  278. // REQUIRE( infix2Postfix("3 + 4 * (9 + 5)") == "3 4 9 5 + * +" );
  279. // REQUIRE( infix2Postfix("(3 + 4) * (9 + 5)") == "3 4 + 9 5 + *" );
  280. }