Advertisement
Guest User

Untitled

a guest
Nov 12th, 2019
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.37 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4. #include <functional>
  5. #include <cmath>
  6. #include <time.h>
  7. #include <cstdlib>
  8.  
  9. using namespace std;
  10.  
  11. class Person {
  12. public:
  13. string name;
  14. int age;
  15.  
  16. Person() {}
  17.  
  18. Person(int age, string name) {
  19. this->name = name;
  20. this->age = age;
  21. }
  22. };
  23.  
  24. int nodeCounter = 1;
  25.  
  26. template<class T>
  27. class Node {
  28. public:
  29. T value;
  30. Node<T> *parent = NULL;
  31. Node<T> *leftKid = NULL;
  32. Node<T> *rightKid = NULL;
  33. bool isRed = true;
  34. int id;
  35.  
  36. Node(T value) {
  37. this->value = value;
  38. this->id = nodeCounter;
  39. nodeCounter++;
  40. }
  41. };
  42.  
  43.  
  44. // globalna zmienna do toStringa
  45. //ostringstream toStringResult;
  46.  
  47.  
  48. template<class T>
  49. class BlackRedTree {
  50. int elementCounter = 0;
  51. Node<T> *root = NULL;
  52. public:
  53.  
  54. ~BlackRedTree() {
  55. clear();
  56. }
  57.  
  58. T *find(T data, function<bool(T, T)> compareElement, function<int(T, T)> compare) {
  59. Node<T> *tmp = root;
  60. while ((tmp != NULL) && !(compareElement(tmp->value, data))) {
  61. if (compare(tmp->value, data) == -1) {
  62. tmp = tmp->leftKid;
  63. } else {
  64. tmp = tmp->rightKid;
  65. }
  66. }
  67. if (tmp == NULL) {
  68. return NULL;
  69. }
  70. return &tmp->value;
  71. }
  72.  
  73. void preOrder(function<void(Node<T> *)> f) {
  74. preOrderRecursion(root, f);
  75. }
  76.  
  77. void inOrder(function<void(Node<T> *)> f) {
  78. inOrderRecursion(root, f);
  79. }
  80.  
  81. void postOrder(function<void(Node<T> *)> f) {
  82. postOrderRecursion(root, f);
  83. }
  84.  
  85. void clear() {
  86. postOrder(clearElement);
  87. }
  88.  
  89. int height() {
  90. return heightRecursion(root);
  91. }
  92.  
  93. void addElement(T data, function<int(T, T)> compare) {
  94. balancing(addElementSimple(data, compare));
  95. }
  96.  
  97. string toString(function<string(T)> f) {
  98. // czyszczenie ostringstreama
  99. // toStringResult.str("");
  100. // preOrder(BlackRedTree::nodeToString);
  101. // return toStringResult.str();
  102.  
  103. ostringstream result;
  104.  
  105. result << "Size: " << elementCounter << endl;
  106. preOrder(
  107. // WYRAZENIE LAMBDA
  108. [&result, &f](Node<T> *node) -> void {
  109. int parentId = node->parent == NULL ? 0 : node->parent->id;
  110. string color = (node->isRed == true) ? "red" : "black";
  111. int leftId = node->leftKid == NULL ? 0 : node->leftKid->id;
  112. int rightId = node->rightKid == NULL ? 0 : node->rightKid->id;
  113. result << " ID: " << node->id <<
  114. " color: " << color <<
  115. " parent id: " << parentId <<
  116. " left id: " << leftId <<
  117. " right id: " << rightId <<
  118. " | " << f(node->value) << endl;
  119.  
  120. }
  121. );
  122. return result.str();
  123. }
  124.  
  125. // static void nodeToString(Node<T> *node) {
  126. // toStringResult << node->isRed << endl;
  127. // }
  128.  
  129. private:
  130. //dodawanie bez rotacji i bez kolorow
  131. Node<T> *addElementSimple(T data, function<int(T, T)> compare) {
  132. Node<T> *node = new Node<T>(data);
  133. if (elementCounter == 0) {
  134. root = node;
  135. elementCounter++;
  136. return node;
  137. }
  138. Node<T> *tmp = root;
  139. while (true) {
  140. int x = compare(data, tmp->value);
  141. if (x == 0 || x == -1) {
  142. if (tmp->leftKid == NULL) {
  143. tmp->leftKid = node;
  144. node->parent = tmp;
  145. elementCounter++;
  146. return node;
  147. } else {
  148. tmp = tmp->leftKid;
  149. }
  150. } else if (tmp->rightKid == NULL) {
  151. tmp->rightKid = node;
  152. node->parent = tmp;
  153. elementCounter++;
  154. return node;
  155. } else {
  156. tmp = tmp->rightKid;
  157. }
  158. }
  159. }
  160.  
  161. void coloringCase1Left(Node<T> *node, Node<T> *father, Node<T> *grandfather, Node<T> *leftUncle) {
  162. father->isRed = false;
  163. leftUncle->isRed = false;
  164. grandfather->isRed = true;
  165. }
  166.  
  167. void coloringCase1Right(Node<T> *node, Node<T> *father, Node<T> *grandfather, Node<T> *rightUncle) {
  168. father->isRed = false;
  169. rightUncle->isRed = false;
  170. grandfather->isRed = true;
  171. }
  172.  
  173. void coloringCase3(Node<T> *father, Node<T> *grandfather) {
  174. father->isRed = !father->isRed;
  175. grandfather->isRed = !grandfather->isRed;
  176.  
  177. }
  178.  
  179. void balancing(Node<T> *node) {
  180. Node<T> *father = NULL;
  181. Node<T> *grandfather = NULL;
  182. Node<T> *leftUncle = NULL;
  183. Node<T> *rightUncle = NULL;
  184.  
  185. while (true) {
  186. father = node->parent;
  187. if (node == root) {
  188. node->isRed = false;
  189. return;
  190. }
  191. if (!father->isRed) {
  192. return;
  193. }
  194. grandfather = father->parent;
  195. leftUncle = grandfather->leftKid;
  196. rightUncle = grandfather->rightKid;
  197.  
  198. if (isLeftUncleRed(father, leftUncle, rightUncle)) {
  199. coloringCase1Left(node, father, grandfather, leftUncle);
  200. node = grandfather;
  201. continue;
  202. }
  203. if (isRightUncleRed(father, leftUncle, rightUncle)) {
  204. coloringCase1Right(node, father, grandfather, rightUncle);
  205. node = grandfather;
  206. continue;
  207. }
  208. break;
  209. }
  210. if (isRightUncleBlack(father, leftUncle, rightUncle) && father->rightKid == node) {
  211. rotationLeft(father);
  212. node = father;
  213. rotationRight(grandfather);
  214. father = node->parent;
  215. Node<T> *brother = father->rightKid;
  216. coloringCase3(father, brother);
  217. return;
  218. }
  219. if (isLeftUncleBlack(father, leftUncle, rightUncle) && father->leftKid == node) {
  220. rotationRight(father);
  221. node = father;
  222. rotationLeft(grandfather);
  223. father = node->parent;
  224. Node<T> *brother = father->leftKid;
  225. coloringCase3(father, brother);
  226. return;
  227. }
  228.  
  229. if (isRightUncleBlack(father, leftUncle, rightUncle) && father->leftKid == node) {
  230. rotationRight(grandfather);
  231. coloringCase3(father, grandfather);
  232. }
  233.  
  234. if (isLeftUncleBlack(father, leftUncle, rightUncle) && father->rightKid == node) {
  235. rotationLeft(grandfather);
  236. coloringCase3(father, grandfather);
  237. }
  238.  
  239. }
  240.  
  241. bool isLeftUncleRed(Node<T> *father, Node<T> *leftUncle, Node<T> *rightUncle) {
  242. if (leftUncle == NULL) {
  243. return false;
  244. }
  245. return (father == rightUncle && leftUncle->isRed);
  246. }
  247.  
  248. bool isRightUncleRed(Node<T> *father, Node<T> *leftUncle, Node<T> *rightUncle) {
  249. if (rightUncle == NULL) {
  250. return false;
  251. }
  252. return (father == leftUncle && rightUncle->isRed);
  253. }
  254.  
  255. bool isRightUncleBlack(Node<T> *father, Node<T> *leftUncle, Node<T> *rightUncle) {
  256. if (rightUncle == NULL) {
  257. return true;
  258. }
  259. return (father == leftUncle && !rightUncle->isRed);
  260. }
  261.  
  262. bool isLeftUncleBlack(Node<T> *father, Node<T> *leftUncle, Node<T> *rightUncle) {
  263. if (leftUncle == NULL) {
  264. return true;
  265. }
  266. return (father == rightUncle && !leftUncle->isRed);
  267. }
  268.  
  269. void rotationRight(Node<T> *start) {
  270. Node<T> *startLeftChild = start->leftKid;
  271. Node<T> *startRightGrandChild = startLeftChild->rightKid;
  272. Node<T> **startPointer = getStartPointer(start);
  273.  
  274. start->leftKid = startRightGrandChild;
  275. startLeftChild->rightKid = start;
  276. startLeftChild->parent = start->parent;
  277. start->parent = startLeftChild;
  278. *startPointer = startLeftChild;
  279. if (
  280. startRightGrandChild) {
  281. startRightGrandChild->parent = start;
  282. }
  283. }
  284.  
  285. void rotationLeft(Node<T> *start) {
  286. Node<T> *startRightChild = start->rightKid;
  287. Node<T> *startLeftGrandChild = startRightChild->leftKid;
  288. Node<T> **startPointer = getStartPointer(start);
  289.  
  290. start->rightKid = startLeftGrandChild;
  291. startRightChild->leftKid = start;
  292. startRightChild->parent = start->parent;
  293. start->parent = startRightChild;
  294. *startPointer = startRightChild;
  295. if (startLeftGrandChild) {
  296. startLeftGrandChild->parent = start;
  297. }
  298. }
  299.  
  300. /**
  301. * zwraca wskaznik na wskaznik na "punkt startowy rotacji"
  302. * "**" zeby mozna bylo zmienic np. roota
  303. */
  304. Node<T> **getStartPointer(Node<T> *start) {
  305. if (start == root) {
  306. return &root;
  307. } else if (start->parent->leftKid == start) {
  308. return &start->parent->leftKid;
  309. } else {
  310. return &start->parent->rightKid;
  311. }
  312. }
  313.  
  314. void preOrderRecursion(Node<T> *node, function<void(Node<T> *)> f) {
  315. f(node);
  316. if (node->leftKid != NULL) {
  317. preOrderRecursion(node->leftKid, f);
  318. }
  319. if (node->rightKid != NULL) {
  320. preOrderRecursion(node->rightKid, f);
  321. }
  322. }
  323.  
  324. void inOrderRecursion(Node<T> *node, function<void(Node<T> *)> f) {
  325. if (node->leftKid != NULL) {
  326. inOrderRecursion(node->leftKid, f);
  327. }
  328. f(node);
  329. if (node->rightKid != NULL) {
  330. inOrderRecursion(node->rightKid, f);
  331. }
  332. }
  333.  
  334. void postOrderRecursion(Node<T> *node, function<void(Node<T> *)> f) {
  335. if (node->leftKid != NULL) {
  336. postOrderRecursion(node->leftKid, f);
  337. }
  338. if (node->rightKid != NULL) {
  339. postOrderRecursion(node->rightKid, f);
  340. }
  341. f(node);
  342. }
  343.  
  344. static void clearElement(Node<T> *node) {
  345. delete node;
  346. }
  347.  
  348. int heightRecursion(Node<T> *node) {
  349. int height = 0;
  350. if (node == NULL) {
  351. return height;
  352. }
  353. int leftHeight = heightRecursion(node->leftKid);
  354. int rightHeight = heightRecursion(node->rightKid);
  355.  
  356. if (leftHeight >= rightHeight) {
  357. leftHeight++;
  358. return leftHeight;
  359. } else {
  360. rightHeight++;
  361. return rightHeight;
  362. }
  363. }
  364.  
  365. };
  366.  
  367. bool compareElement(Person person, Person pattern) {
  368. if (person.age == pattern.age) {
  369. return true;
  370. } else {
  371. return false;
  372. }
  373. }
  374.  
  375. int compare(Person newPerson, Person elem) {
  376. if (newPerson.age == elem.age) {
  377. return 0;
  378. } else if (newPerson.age < elem.age) {
  379. return -1;
  380. } else {
  381. return 1;
  382. }
  383. }
  384.  
  385. bool compareElementInt(int number, int pattern) {
  386. return number == pattern;
  387. }
  388.  
  389. int compareInt(int number, int pattern) {
  390. if (number == pattern) {
  391. return 0;
  392. } else if (number < pattern) {
  393. return -1;
  394. } else {
  395. return 1;
  396. }
  397. }
  398.  
  399. string intToString(int n) {
  400. ostringstream ss;
  401. ss << n;
  402. return ss.str();
  403. }
  404.  
  405. void print(Node<int> *x) {
  406. cout << x->value << endl;
  407. }
  408.  
  409. string personToString(Person p) {
  410. ostringstream result; //zamiana inta na stringa
  411. result << "age: " << p.age << ", " << "imie: " << p.name;
  412. return result.str();
  413. }
  414.  
  415. void treeTest(int n) {
  416. BlackRedTree<Person> brt;
  417. Person *persons = new Person[n];
  418.  
  419. clock_t t1 = clock();
  420. for (int i = 0; i < n; ++i) {
  421. // cout << i << "/" << n << endl;
  422. persons[i].age = i + 1;
  423. persons[i].name = "xyz";
  424. brt.addElement(persons[i], compare);
  425. }
  426. clock_t t2 = clock();
  427. double addTime = (t2 - t1) / (double) CLOCKS_PER_SEC;
  428. cout << "czas dodawania: " << addTime << endl;
  429. cout << "czas sredni dodawania: " << addTime / n << endl;
  430. cout << "wysokosc drzewa: " << brt.height() << endl;
  431.  
  432.  
  433. const int m = pow(10, 4);
  434. int hits = 0;
  435. t1 = clock();
  436. for (int i = 0; i < m; i++) {
  437. int age = (rand() % n) + 1;
  438. //int age = (rand()<<15) + rand();
  439. Person person(age, "xyz");
  440. Person *result = brt.find(person, compareElement, compare);
  441. if (result != NULL)
  442. hits++;
  443. }
  444. t2 = clock();
  445. double findTime = (t2 - t1) / (double) CLOCKS_PER_SEC;
  446. cout << "czas wyszukiwania: " << findTime << endl;
  447. cout << "czas sredni wyszukiwania: " << findTime / m << endl;
  448. cout << "liczba trafien: " << hits << endl;
  449.  
  450. //cout << brt.toString(personToString);
  451.  
  452. delete[] persons;
  453. }
  454.  
  455.  
  456. int main() {
  457. srand(time(NULL));
  458.  
  459. const int MAX_ORDER = 7;
  460.  
  461. for (int o = 1; o <= MAX_ORDER; o++) {
  462. int n = pow(10, o);
  463. cout << n;
  464. treeTest(n);
  465. cout << " - " << endl;
  466. }
  467.  
  468.  
  469. // BlackRedTree<int> brt;
  470. // for (int i = 0; i < 8; ++i) {
  471. // brt.addElement(i + 1, compareInt);
  472. //
  473. // }
  474. // cout << brt.toString(intToString) << endl;
  475.  
  476. // brt.find(3, compareElementInt, compareInt);
  477. // brt.postOrder(print);
  478. // cout << endl;
  479. //
  480. // cout << brt.height() << endl << endl;
  481. //
  482. // cout << brt.toString(intToString) << endl;
  483.  
  484.  
  485. return 0;
  486. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement