Advertisement
Guest User

Untitled

a guest
Nov 21st, 2019
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.39 KB | None | 0 0
  1. // ALGO2 IS1 212B LAB05
  2. // Marcel Iwanicki
  3. // im44337@zut.edu.pl
  4.  
  5. #include <iostream>
  6. #include <cstdio>
  7. #include <cstring>
  8. #include <ctime>
  9. #include <fstream>
  10.  
  11. namespace util {
  12. inline int generateRandomInteger(int min, int max) {
  13. return (std::rand() % (max - min)) + min;
  14. }
  15.  
  16. inline unsigned int max(unsigned int a, unsigned int b) {
  17. if(a > b)
  18. return a;
  19. return b;
  20. }
  21. }
  22.  
  23. struct Node {
  24. int key;
  25. char key_string[10];
  26.  
  27. Node* leftChild;
  28. Node* rightChild;
  29.  
  30. Node(int key) : key(key) {
  31. leftChild = nullptr;
  32. rightChild = nullptr;
  33.  
  34. std::sprintf(key_string, "%d", key);
  35. }
  36.  
  37.  
  38. bool isLeaf() {
  39. return (leftChild == nullptr && rightChild == nullptr);
  40. }
  41.  
  42. bool hasOnlyOneChild() {
  43. return hasOnlyLeftChild() || hasOnlyRightChild();
  44. }
  45.  
  46. bool hasOnlyLeftChild() {
  47. return (rightChild == nullptr);
  48. }
  49.  
  50. bool hasOnlyRightChild() {
  51. return (leftChild == nullptr);
  52. }
  53.  
  54. bool hasTwoChildren() {
  55. return (leftChild != nullptr && rightChild != nullptr);
  56. }
  57.  
  58. Node* getSmallestNodeInRightSubtree() {
  59. Node *tmp = this->rightChild;
  60.  
  61. while(tmp != nullptr && tmp->leftChild != nullptr) {
  62. tmp = tmp->leftChild;
  63. }
  64.  
  65. return tmp;
  66. }
  67.  
  68. void assignValues(const Node* node) {
  69. this->key = node->key;
  70. std::strcpy(this->key_string, node->key_string);
  71. }
  72.  
  73. friend std::ostream&operator<<(std::ostream& out, const Node* node) {
  74. std::cout << "Node={key=" << node->key << ", key_string=" << std::string(node->key_string) << "}";
  75. return out;
  76. }
  77.  
  78. };
  79.  
  80. class BinarySearchTree {
  81. private:
  82. Node* root;
  83. unsigned int size;
  84.  
  85. public:
  86. BinarySearchTree() {
  87. std::srand(std::time(nullptr));
  88. root = nullptr;
  89. size = 0;
  90. }
  91.  
  92. bool add(int key) {
  93. Node* node = new Node(key);
  94. if(root == nullptr) { // nie istnieje korzen
  95. root = node;
  96. size++;
  97. return true;
  98. } else { // korzen juz istnieje
  99. Node* tmp = root;
  100. while(true) {
  101. if(node->key < tmp->key) {
  102. if(tmp->leftChild == nullptr) { // znaleziono miejsce
  103. tmp->leftChild = node;
  104. size++;
  105.  
  106. return true;
  107. }
  108. tmp = tmp->leftChild;
  109.  
  110. } else if(node->key > tmp->key) {
  111. if(tmp->rightChild == nullptr) { // znaleziono miejsce
  112. tmp->rightChild = node;
  113. size++;
  114.  
  115. return true;
  116. }
  117. tmp = tmp->rightChild;
  118.  
  119. } else {
  120. std::cout << "ERROR: w drzewie JUZ znajduje sie wezel o kluczu " << node->key << std::endl;
  121. return false;
  122. }
  123. }
  124. }
  125. }
  126.  
  127. void addManyRandom(unsigned int n) {
  128. for (int i = 0; i < n; ++i) {
  129. unsigned int key = util::generateRandomInteger(-1000, 1000);
  130. while(!this->add(key)) {
  131. key = util::generateRandomInteger(-1000, 1000);
  132. }
  133. }
  134. }
  135.  
  136. Node* find(int key) {
  137. Node* tmp = root;
  138. while(tmp != nullptr) {
  139. if(key < tmp->key) {
  140. tmp = tmp->leftChild;
  141. } else if(key > tmp->key) {
  142. tmp = tmp->rightChild;
  143. } else { //znaleziono wezel
  144. return tmp;
  145. }
  146. }
  147. return nullptr;
  148. }
  149.  
  150. void show(int key) {
  151. Node* result = this->find(key);
  152. if(result == nullptr)
  153. std::cout << "ERROR: nie znaleziono wezla o kluczu " << key << std::endl;
  154. else
  155. std::cout << result << std::endl;
  156. }
  157.  
  158. Node *getParent(int key) {
  159. if(key == root->key) {
  160. return nullptr;
  161. }
  162.  
  163. Node* tmp = root;
  164. while(tmp != nullptr) {
  165. if((tmp->leftChild != nullptr && tmp->leftChild->key == key)
  166. || (tmp->rightChild != nullptr && tmp->rightChild->key == key))
  167. return tmp;
  168.  
  169. if(key < tmp->key) {
  170. tmp = tmp->leftChild;
  171. } else if(key > tmp->key) {
  172. tmp = tmp->rightChild;
  173. }
  174. }
  175.  
  176. return nullptr;
  177. }
  178.  
  179. bool remove(int key) {
  180. Node* found = this->find(key);
  181. if(found == nullptr) { // nie znaleziono wezla
  182. return false;
  183. }
  184.  
  185. Node* parent = this->getParent(key);
  186.  
  187. if(found->isLeaf()) {
  188. removeLeaf(found, parent);
  189. size--;
  190.  
  191. return true;
  192. }
  193. else if(found->hasOnlyOneChild()) {
  194. removeNodeWithOnlyOneChild(found, parent);
  195. size--;
  196.  
  197. return true;
  198. }
  199. else if (found->hasTwoChildren()){
  200. removeNodeWithBothChildren(found, parent);
  201. size--;
  202.  
  203. return true;
  204. }
  205.  
  206. return false;
  207. }
  208.  
  209. void removeLeaf(Node* leaf, Node* parent) {
  210. if(parent->leftChild == leaf) { // leaf jest lewym dzieckiem
  211. parent->leftChild = nullptr;
  212. delete parent->leftChild;
  213. } else if(parent->rightChild == leaf) { // leaf jest prawym dzieckiem
  214. parent->rightChild = nullptr;
  215. delete parent->rightChild;
  216. }
  217. }
  218.  
  219. void removeNodeWithOnlyOneChild(Node* node, Node* parent) {
  220. if(node == root) {
  221. if(root->leftChild != nullptr) {
  222. root = root->leftChild;
  223. }
  224. else if(root->rightChild != nullptr) {
  225. root = root->rightChild;
  226. }
  227. }
  228.  
  229. else if(node->hasOnlyLeftChild()) {
  230. if(parent->leftChild == node) { // node jest lewym dzieckiem
  231. parent->leftChild = node->leftChild;
  232. delete node;
  233. } else if(parent->rightChild == node) {// node jest prawym dzieckiem
  234. parent->rightChild = node->leftChild;
  235. delete node;
  236. }
  237.  
  238. } else if(node->hasOnlyRightChild()) {
  239. if (parent->leftChild == node) { // node jest lewym dzieckiem
  240. parent->leftChild = node->rightChild;
  241. delete node;
  242. } else if (parent->rightChild == node) {// node jest prawym dzieckiem
  243. parent->rightChild = node->rightChild;
  244. delete node;
  245. }
  246. }
  247. }
  248.  
  249. void removeNodeWithBothChildren(Node* node, Node* parent) {
  250. Node* smallestNodeInRightSubtree = node->getSmallestNodeInRightSubtree();
  251. Node* smallestNodeInRightSubtree_parent = getParent(smallestNodeInRightSubtree->key);
  252.  
  253. node->assignValues(smallestNodeInRightSubtree);
  254.  
  255. if(smallestNodeInRightSubtree->isLeaf()) {
  256. removeLeaf(smallestNodeInRightSubtree, smallestNodeInRightSubtree_parent);
  257. }
  258. else if(smallestNodeInRightSubtree->hasOnlyOneChild()) {
  259. removeNodeWithOnlyOneChild(smallestNodeInRightSubtree, smallestNodeInRightSubtree_parent);
  260. }
  261. }
  262.  
  263. enum class DfsType {
  264. PRE_ORDER,
  265. IN_ORDER,
  266. POST_ORDER,
  267. };
  268.  
  269. void dfs(DfsType type) {
  270. switch (type) {
  271. case DfsType::PRE_ORDER:
  272. std::cout << "\n===: PreOrder Depth First Search :===" << std::endl;
  273. dfsPreOrder(root);
  274. break;
  275. case DfsType::IN_ORDER:
  276. std::cout << "\n===: InOrder Depth First Search :===" << std::endl;
  277. dfsInOrder(root);
  278. break;
  279. case DfsType::POST_ORDER:
  280. std::cout << "\n===: PostOrder Depth First Search :===" << std::endl;
  281. dfsPostOrder(root);
  282. break;
  283. default:
  284. std::cout << "NIEPOPRAWNY WYBOR DFS" << std::endl;
  285. break;
  286. }
  287. }
  288.  
  289. void makeBackbone() {
  290. Node* parentTmp = root;
  291. Node* grandFather = nullptr;
  292.  
  293. while(parentTmp != nullptr) {
  294. if(parentTmp->leftChild == nullptr) {
  295. Node* grandFather = parentTmp;
  296. parentTmp = parentTmp->rightChild;
  297. } else {
  298. Node * childTmp = parentTmp->leftChild;
  299. rotateRight(childTmp, parentTmp, grandFather);
  300. parentTmp = childTmp;
  301. }
  302. }
  303. }
  304.  
  305. void performDsw() {
  306.  
  307. Node* childTmp = nullptr;
  308. Node* parentTmp = root;
  309. Node* grandParentTmp = nullptr;
  310.  
  311. unsigned int treeSize = getSize();
  312. unsigned int k = 1;
  313. while(k <= treeSize)
  314. k = 2*k+1;
  315. k = k / 2;
  316.  
  317. for (int i = 0; i < (treeSize - k); ++i) {
  318.  
  319. childTmp = parentTmp->rightChild;
  320. if(childTmp != nullptr) {
  321. rotateLeft(parentTmp->rightChild, parentTmp, grandParentTmp);
  322. grandParentTmp = childTmp;
  323. parentTmp = childTmp->rightChild;
  324. }
  325. }
  326.  
  327. while (k > 1) {
  328. k = k / 2;
  329. grandParentTmp = nullptr;
  330. parentTmp = root;
  331. for (int i = 0; i < k; ++i) {
  332.  
  333. childTmp = parentTmp->rightChild;
  334. rotateLeft(parentTmp->rightChild, parentTmp, grandParentTmp);
  335. grandParentTmp = childTmp;
  336. parentTmp = childTmp->rightChild;
  337. }
  338. }
  339. }
  340.  
  341. unsigned int getHeight(Node* current) {
  342. if(current == nullptr) { // root jest nullem
  343. return 0;
  344. }
  345.  
  346. unsigned int leftHeight = getHeight(current->leftChild);
  347. unsigned int rightHeight = getHeight(current->rightChild);
  348. return (util::max(leftHeight, rightHeight) + 1);
  349. }
  350.  
  351. unsigned int getHeight() {
  352. return getHeight(root);
  353. }
  354.  
  355. unsigned int getSize() const {
  356. return size;
  357. }
  358.  
  359. private:
  360. void dfsPreOrder(Node* start) {
  361. if(start == nullptr)
  362. return;
  363.  
  364. std::cout << start << std::endl;
  365. dfsPreOrder(start->leftChild);
  366. dfsPreOrder(start->rightChild);
  367. }
  368.  
  369.  
  370. void dfsInOrder(Node* start) {
  371. if(start == nullptr)
  372. return;
  373.  
  374. dfsInOrder(start->leftChild);
  375. std::cout << start << std::endl;
  376. dfsInOrder(start->rightChild);
  377. }
  378.  
  379. void dfsPostOrder(Node* start) {
  380. if(start == nullptr)
  381. return;
  382.  
  383. dfsPostOrder(start->leftChild);
  384. dfsPostOrder(start->rightChild);
  385. std::cout << start << std::endl;
  386. }
  387.  
  388. void rotateLeft(Node* child, Node* parent, Node* grandParent) {
  389.  
  390. if (grandParent != nullptr) {
  391. if (grandParent->rightChild == parent)
  392. grandParent->rightChild = child;
  393. else if (grandParent->leftChild == parent)
  394. grandParent->leftChild = child;
  395. } else {
  396. root = child;
  397. }
  398.  
  399. Node *tmp = child->leftChild;
  400. child->leftChild = parent;
  401. parent->rightChild = tmp;
  402.  
  403. }
  404.  
  405. void rotateRight(Node* child, Node* parent, Node* grandParent) {
  406.  
  407. if (grandParent != nullptr) {
  408.  
  409. if (grandParent->rightChild == parent)
  410. grandParent->rightChild = child;
  411. else if (grandParent->leftChild == parent)
  412. grandParent->leftChild = child;
  413.  
  414. } else {
  415. root = child;
  416. }
  417.  
  418. Node *tmp = child->rightChild;
  419. child->rightChild = parent;
  420. parent->leftChild = tmp;
  421.  
  422. }
  423. };
  424.  
  425. struct FileStructure {
  426. unsigned int X1;
  427. unsigned int X2;
  428. };
  429.  
  430. FileStructure readFile(const std::string& path);
  431.  
  432. int main() {
  433. FileStructure fileStructure = readFile("inlab05.txt");
  434. BinarySearchTree tree;
  435.  
  436. tree.addManyRandom(fileStructure.X1);
  437. std::cout << tree.getHeight() << std::endl;
  438. tree.makeBackbone();
  439. tree.performDsw();
  440. std::cout << tree.getHeight() << std::endl;
  441. // tree.removeAll();
  442. }
  443.  
  444. FileStructure readFile(const std::string& path) {
  445. FileStructure fileStructure;
  446. std::fstream file;
  447. file.open(path);
  448.  
  449. if(file.good()) {
  450. file >> fileStructure.X1;
  451. file >> fileStructure.X2;
  452. }
  453.  
  454. return fileStructure;
  455. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement