Advertisement
Guest User

Untitled

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