Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.44 KB | None | 0 0
  1. #include "pch.h"
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #pragma warning(disable:4996)
  8.  
  9. struct elem {
  10. int x;
  11. int y;
  12. char* info;
  13. };
  14.  
  15. struct itemList {
  16. elem* data;
  17. itemList* prev;
  18. itemList* next;
  19. };
  20.  
  21. struct Node {
  22. int busy;
  23. float xmax;
  24. float xmin;
  25. float ymax;
  26. float ymin;
  27. Node* child;
  28. itemList itemshead;
  29. };
  30.  
  31. struct QTree {
  32. int N;
  33. int n;
  34. Node* root;
  35. FILE* fd;
  36. char* filename;
  37. };
  38.  
  39. const char *msgs[] = { "0. Quit", "1. Add new element", "2. Find an element", "3. Delete an element", "4. Show table", "5. Save table", "6. Table properties", "7. Timing"};
  40. const char *errmsgs[] = { "Ok", "Error: Duplicate key 1", "Error: Duplicate key 2", "Error: Table overflow", "Table nullpointer", "Data nullptr" };
  41. const int NMsgs = sizeof(msgs) / sizeof(msgs[0]);
  42. const char *errmsgsdel[] = { "Ok", "Error: item not found" , "Table nullpointer", "Wrong keyspace" };
  43. const char *errload[] = { "Ok", "Tree nullptr", "Filename nullptr", "N is negative" };
  44. const char *errsave[] = { "Ok", "Nullptr file descriptor" };
  45. const char *errins[] = { "Ok", "Tree nullptr", "Element nullptr", "Error: this point already exists", "Incorrect keys: the point doesn\'t fit into the tree" };
  46. const char *errdel[] = {"Ok", ""};
  47. const char *showmsgs[] = { "1. X direct order", "2. Keys range", "3. Tree view" };
  48.  
  49. int dload(QTree* t);
  50. int dsave(QTree* t);
  51. int delTree(QTree* t);
  52. int dinsert(QTree* t);
  53. int dsearch(QTree* t);
  54. int dremove(QTree* t);
  55. int dshow(QTree* t);
  56. int properties(QTree *t);
  57. int save(QTree* t);
  58. int rmv(QTree* t, int x, int y);
  59. int insert(QTree* t, elem* e);
  60. int getInt(int* t, int mode);
  61. int createTree(QTree* t, char* fname, int xmin, int xmax, int ymin, int ymax, int N);
  62. int createFile(QTree* t, char* fname);
  63. int load(QTree* t, char* fname);
  64. int dialog(const char* msgs[], int N);
  65. int quadrant(int x, int y, float xmin, float xmax, float ymin, float ymax);
  66. int divide(Node* parent);
  67. int linsert(elem* item, itemList* head);
  68. char* getStr(int mode);
  69. char* makeStr(const char buf[]);
  70. int search(QTree* t, Node** node, itemList** answer, int x, int y);
  71. itemList*** traverse(Node* node, itemList*** arrptr, int* n);
  72. int showXDirectOrder(QTree* t);
  73. int showRange(QTree* t);
  74. int inRange(itemList*, int xmin, int xmax, int ymin, int ymax);
  75. int showTree(QTree* t);
  76. int treeView(Node* r, int lvl);
  77. int delNode(Node* r, int i);
  78. int timing(QTree* t);
  79.  
  80. int(*sfptr[])(QTree*) = { NULL, showXDirectOrder, showRange, showTree };
  81. int(*fptr[])(QTree*) = { NULL, dinsert, dsearch, dremove, dshow, dsave, properties, timing};
  82.  
  83. int timing(QTree* t) {
  84. QTree testTree = { 0, NULL, NULL };
  85. createTree(&testTree, NULL, INT_MIN, INT_MAX, INT_MIN, INT_MAX, 10);
  86. clock_t first, last;
  87. int n = 10, x[100000], y[100000], cnt = 400000, i, m;
  88. srand(time(NULL));
  89. while (n-- > 0) {
  90. for (i = 0; i < 100000; ++i) {
  91. x[i] = i;
  92. y[i] = i;
  93. }
  94. for (i = 0; i < cnt; ) {
  95. elem* te = (elem*)malloc(sizeof(elem));
  96. char* info = makeStr("text");
  97. te->x = rand();
  98. te->y = rand();
  99. te->info = info;
  100. if (!insert(&testTree, te)) ++i;
  101. }
  102. m = 0;
  103. first = clock();
  104. for (i = 0; i < 100000; i++) {
  105. itemList* ans;
  106. Node*r = testTree.root;
  107. search(&testTree, &r, &ans, x[i], y[i]);
  108. if (ans) m++;
  109. }
  110. last = clock();
  111. printf("%d items were found\n", m);
  112. printf("test #%d, number of nodes = %d, time = %d\n", 10 - n, (10 - n)*cnt, last - first);
  113. }
  114. delTree(&testTree);
  115. return 1;
  116. }
  117.  
  118. int delNode(Node* r, int i) {
  119. itemList* tmp = r->itemshead.next;
  120. while (tmp) {
  121. free(tmp->data->info);
  122. free(tmp->data);
  123. itemList* next = tmp->next;
  124. free(tmp);
  125. tmp = next;
  126. }
  127. if (r->child) for (int i = 3; i >= 0; i--) delNode(&(r->child[i]), i);
  128. if (!i) free(r);
  129. return 0;
  130. }
  131.  
  132. int treeView(Node* r, int lvl) {
  133. printf("\n");
  134. for (int i = 0; i < lvl; i++) printf("\t");
  135. printf("lvl%d [(%.0f; %.0f) - (%.0f; %.0f)] Busy %d\n", lvl, r->xmin, r->ymin, r->xmax, r->ymax, r->busy);
  136. if (r->busy) {
  137. itemList* tmp = r->itemshead.next;
  138. while (tmp) {
  139. for (int i = 0; i < lvl; i++) printf("\t");
  140. printf("(%d; %d) %s\n", tmp->data->x, tmp->data->y, tmp->data->info);
  141. tmp = tmp->next;
  142. }
  143. }
  144. if (r->child) {
  145. lvl++;
  146. for (int i = 0; i < 4; i++) treeView(&r->child[i], lvl);
  147. }
  148. return 0;
  149. }
  150.  
  151. int inRange(itemList* item, int xmin, int xmax, int ymin, int ymax) {
  152. int x = item->data->x, y = item->data->y;
  153. if (x >= xmin && x <= xmax && y <= ymax && y >= ymin) return 1;
  154. else return 0;
  155. }
  156.  
  157. int showRange(QTree* t) {
  158. int xmin, xmax, ymin, ymax;
  159. printf("Enter key range:\n");
  160. printf("Min x: -->");
  161. getInt(&xmin, -1);
  162. printf("Max x: -->");
  163. getInt(&xmax, -1);
  164. printf("Min y: -->");
  165. getInt(&ymin, -1);
  166. printf("Max y: -->");
  167. getInt(&ymax, -1);
  168. if (xmin > t->root->xmax || xmax < t->root->xmin || ymin > t->root->ymax || ymax < t->root->xmin) {
  169. printf("This area doesn't belong to the tree\n");
  170. return 1;
  171. }
  172. itemList** arrptr = (itemList**)malloc(t->n * sizeof(itemList*));
  173. int n = 0;
  174. traverse(t->root, &arrptr, &n);
  175. for (int i = 0; i < n; i++)
  176. if (inRange(arrptr[i], xmin, xmax, ymin, ymax))
  177. printf("%d\t%d\t%s\n", arrptr[i]->data->x, arrptr[i]->data->y, arrptr[i]->data->info);
  178. return 1;
  179. }
  180.  
  181. int properties(QTree* t) {
  182. if (!t) return 1;
  183. printf("Busy: %d\n", t->n);
  184. printf("Node capacity: %d\n", t->N);
  185. printf("Filename: %s\n", t->filename);
  186. return 1;
  187. }
  188.  
  189. itemList*** traverse(Node* node, itemList*** arrptr, int* n) {
  190. if (node->child == NULL) {
  191. itemList* tmp = node->itemshead.next;
  192. while (tmp) {
  193. (*arrptr)[*n] = tmp;
  194. (*n)++;
  195. tmp = tmp->next;
  196. }
  197. return arrptr;
  198. }
  199. else {
  200. arrptr = traverse(&node->child[2], arrptr, n);
  201. arrptr = traverse(&node->child[3], arrptr, n);
  202. arrptr = traverse(&node->child[1], arrptr, n);
  203. arrptr = traverse(&node->child[0], arrptr, n);
  204. }
  205. }
  206.  
  207. int showXDirectOrder(QTree* t) {
  208. itemList** arrptr = (itemList**)malloc(t->n * sizeof(itemList*));
  209. int n = 0;
  210. traverse(t->root, &arrptr, &n);
  211. if (!n) {
  212. printf("Table is empty\n");
  213. return 1;
  214. }
  215. printf("X\tY\tInfo\n");
  216. for (int i = 0; i < n; i++) printf("%d\t%d\t%s\n", arrptr[i]->data->x, arrptr[i]->data->y, arrptr[i]->data->info);
  217. free(arrptr);
  218. return 0;
  219. }
  220.  
  221. int showTree(QTree* t) {
  222. Node* r = t->root;
  223. treeView(r, 0);
  224. return 1;
  225. }
  226.  
  227. int dshow(QTree* t) {
  228. if (!t) return 1;
  229. if (!t->n) {
  230. printf("Tree is empty\n");
  231. return 2;
  232. }
  233. int k;
  234. do {
  235. for (int i = 0; i < 3; i++) printf("%s\n", showmsgs[i]);
  236. printf("Choose your destiny: -->");
  237. getInt(&k, 1);
  238. if (k > 3) printf("I don\'t understand you!!11!n");
  239. } while (k > 3);
  240. if (sfptr[k](t)) printf("Ok\n");
  241. return 1;
  242. }
  243.  
  244. int dsearch(QTree* t) {
  245. if (!t) return 1;
  246. int x, y;
  247. printf("Enter x-->");
  248. getInt(&x, -1);
  249. printf("Enter y -->");
  250. getInt(&y, -1);
  251. itemList* ans = NULL;
  252. Node* r = t->root;
  253. search(t, &r, &ans, x, y);
  254. if (!ans) printf("Item not found\n");
  255. else {
  256. printf("X: %d\n", ans->data->x);
  257. printf("Y: %d\n", ans->data->y);
  258. printf("Info: %s\n", ans->data->info);
  259. }
  260. return 1;
  261. }
  262.  
  263. int rmv(QTree*t, int x, int y) {
  264. Node*r = t->root;
  265. itemList* ans = NULL;
  266. search(t, &r, &ans, x, y);
  267. if (!r) return 1;
  268. if (!ans) return 1;
  269. ans->prev->next = ans->next;
  270. if (ans->next) ans->next->prev = ans->prev;
  271. free(ans->data->info);
  272. free(ans->data);
  273. free(ans);
  274. r->busy--;
  275. t->n--;
  276. return 0;
  277. }
  278.  
  279. int dremove(QTree* t) {
  280. int x, y;
  281. printf("Enter x -->");
  282. getInt(&x, -1);
  283. printf("Enter y -->");
  284. getInt(&y, -1);
  285. int rc = rmv(t, x, y);
  286. printf("%s", errdel[rc]);
  287. return 1;
  288. }
  289.  
  290. int dsave(QTree*t) {
  291. if (!t) return 0;
  292. int rc = save(t);
  293. printf("%s", errsave[rc]);
  294. return 1;
  295. }
  296.  
  297. int save(QTree* t) {
  298. if (!t->fd) return 1;
  299. fseek(t->fd, 0, SEEK_SET);
  300. fwrite(&t->n, sizeof(int), 1, t->fd);
  301. itemList** items = (itemList**)malloc(t->n * sizeof(itemList*));
  302. int n = 0;
  303. traverse(t->root, &items, &n);
  304. for (int i = 0; i < n; i++) {
  305. fwrite(&items[i]->data->x, sizeof(int), 1, t->fd);
  306. fwrite(&items[i]->data->y, sizeof(int), 1, t->fd);
  307. int len = strlen(items[i]->data->info) + 1;
  308. fwrite(&len, sizeof(int), 1, t->fd);
  309. fwrite(items[i]->data->info, sizeof(char), len, t->fd);
  310. }
  311. fseek(t->fd, 0, SEEK_SET);
  312. free(items);
  313. return 0;
  314. }
  315.  
  316. int delTree(QTree* t) {
  317. Node* r = t->root;
  318. delNode(r, 0);
  319. if (t->filename) free(t->filename);
  320. return 0;
  321. }
  322.  
  323. int linsert(elem* item, itemList* head) {
  324. itemList *tmp = head;
  325. itemList* newl = (itemList*)calloc(1, sizeof(itemList));
  326. newl->data = item;
  327. while (tmp->next) {
  328. if (tmp->next->data->x > item->x) break;
  329. if (tmp->next->data->x == item->x) {
  330. if (tmp->next->data->y == item->y) return 1;
  331. if (tmp->next->data->y > item->y) break;
  332. }
  333. tmp = tmp->next;
  334. }
  335. if (tmp->next) {
  336. tmp->next->prev = newl;
  337. newl->prev = tmp;
  338. newl->next = tmp->next;
  339. tmp->next = newl;
  340. }
  341. else {
  342. tmp->next = newl;
  343. newl->prev = tmp;
  344. }
  345. return 0;
  346. }
  347.  
  348. int quadrant(int x, int y, float xmin, float xmax, float ymin, float ymax) {
  349. if (x < xmin || x > xmax || y < ymin || y > ymax) return -1;
  350. if (x >= (xmax + xmin) / 2) {
  351. if (y >= (ymax+ymin) / 2) return 0;
  352. else return 1;
  353. }
  354. else {
  355. if (y >= (ymax+ymin) / 2) return 3;
  356. else return 2;
  357. }
  358. }
  359.  
  360. int search(QTree* t, Node** node, itemList** answer, int x, int y) {
  361. while ((*node)->child) {
  362. int q = quadrant(x, y, (*node)->xmin, (*node)->xmax, (*node)->ymin, (*node)->ymax);
  363. if (q == -1) return 1;
  364. *node = &(*node)->child[q];
  365. }
  366. *answer = (*node)->itemshead.next;
  367. while (*answer) {
  368. if ((*answer)->data->x == x && (*answer)->data->y == y) return 0;
  369. else *answer = (*answer)->next;
  370. }
  371. return 0;
  372. }
  373.  
  374. int insert(QTree* t, elem* e) {
  375. if (!t) return 1;
  376. if (!e) return 2;
  377. if (e->x > t->root->xmax || e->x < t->root->xmin || e->y > t->root->ymax || e->y < t->root->ymin) {
  378. free(e->info);
  379. free(e);
  380. return 4;
  381. }
  382. Node *r = t->root;
  383. itemList* ans = NULL;
  384. search(t, &r, &ans, e->x, e->y);
  385. if (ans) {
  386. free(e->info);
  387. free(e);
  388. return 3;
  389. }
  390. while (r->busy == t->N) {
  391. divide(r);
  392. int q = quadrant(e->x, e->y, r->xmin, r->xmax, r->ymin, r->ymax);
  393. r = &r->child[q];
  394. }
  395. linsert(e, &r->itemshead);
  396. r->busy++;
  397. t->n++;
  398. return 0;
  399. }
  400.  
  401. int dinsert(QTree*t) {
  402. if (!t) return 0;
  403. int x, y;
  404. char* info;
  405. printf("Enter x: ->");
  406. getInt(&x, 1);
  407. printf("Enter y: ->");
  408. getInt(&y, 1);
  409. printf("Enter info:\n");
  410. info = getStr(1);
  411. elem* e = (elem*)malloc(sizeof(elem));
  412. e->x = x;
  413. e->y = y;
  414. e->info = info;
  415. int rc = insert(t, e);
  416. printf("%s\n", errins[rc]);
  417. return 1;
  418. }
  419.  
  420. int divide(Node* parent) {
  421. if (!parent) return 1;
  422. parent->child = (Node*)malloc(4 * sizeof(Node));
  423. for (int i = 0; i < 4; i++) {
  424. parent->child[i].busy = 0;
  425. parent->child[i].busy = 0;
  426. parent->child[i].itemshead.data = NULL;
  427. parent->child[i].itemshead.next = NULL;
  428. parent->child[i].itemshead.prev = NULL;
  429. parent->child[i].child = NULL;
  430. }
  431. parent->child[0].xmin = (parent->xmin + parent->xmax) / 2;
  432. parent->child[0].xmax = parent->xmax;
  433. parent->child[0].ymin = (parent->ymin + parent->ymax) / 2;
  434. parent->child[0].ymax = parent->ymax;
  435. parent->child[1].xmin = (parent->xmin + parent->xmax) / 2;
  436. parent->child[1].xmax = parent->xmax;
  437. parent->child[1].ymin = parent->ymin;
  438. parent->child[1].ymax = (parent->ymin + parent->ymax) / 2;
  439. parent->child[2].xmin = parent->xmin;
  440. parent->child[2].xmax = (parent->xmin + parent->xmax) / 2;
  441. parent->child[2].ymin = parent->ymin;
  442. parent->child[2].ymax = (parent->ymin + parent->ymax) / 2;
  443. parent->child[3].xmin = parent->xmin;
  444. parent->child[3].xmax = (parent->xmin + parent->xmax) / 2;
  445. parent->child[3].ymin = (parent->ymin + parent->ymax) / 2;
  446. parent->child[3].ymax = parent->ymax;
  447. itemList* tmp = parent->itemshead.next;
  448. while (tmp) {
  449. int q = quadrant(tmp->data->x, tmp->data->y, parent->xmin, parent->xmax, parent->ymin, parent->ymax);
  450. linsert(tmp->data, &parent->child[q].itemshead);
  451. parent->child[q].busy++;
  452. itemList* tmp1 = tmp;
  453. tmp = tmp->next;
  454. free(tmp1);
  455. }
  456. parent->itemshead.next = NULL;
  457. parent->busy = 0;
  458. return 0;
  459. }
  460.  
  461. int createFile(QTree*t, char* fname) {
  462. if (!t) return 1;
  463. if (!fname) return 2;
  464. fopen_s(&(t->fd), fname, "w+b");
  465. return 0;
  466. }
  467.  
  468. int load(QTree *t, char *fname) {
  469. if (!t) return 1;
  470. if (!fname) return 2;
  471. fopen_s(&t->fd, fname, "r+b");
  472. if (!t->fd) return 3;
  473. t->filename = fname;
  474. int n;
  475. fread(&n, sizeof(int), 1, t->fd);
  476. int errs = 0;
  477. for (int i = 0; i < n; i++) {
  478. elem *tmp = (elem*)calloc(1, sizeof(elem));
  479. fread(&tmp->x, sizeof(int), 1, t->fd);
  480. fread(&tmp->y, sizeof(int), 1, t->fd);
  481. int len;
  482. fread(&len, sizeof(int), 1, t->fd);
  483. char* info = (char*)malloc(len);
  484. *info = '\0';
  485. tmp->info = info;
  486. fread(tmp->info, sizeof(char), len, t->fd);
  487. if (insert(t, tmp) == 4) errs++;
  488. }
  489. if (errs) printf("%d points weren\'t loaded because they don\'t fit the tree\n", errs);
  490. return 0;
  491. }
  492.  
  493.  
  494. int dload(QTree *t) {
  495. int rc = 1, xmin, xmax, ymin, ymax, N;
  496. char* fname = NULL;
  497. while(rc) {
  498. printf("Enter file name: --> ");
  499. fname = getStr(0);
  500. if (!fname) return 0;
  501. printf("Enter key range:\n");
  502. printf("Min x: -->");
  503. getInt(&xmin, -1);
  504. printf("Max x: -->");
  505. getInt(&xmax, -1);
  506. printf("Min y: -->");
  507. getInt(&ymin, -1);
  508. printf("Max y: -->");
  509. getInt(&ymax, -1);
  510. printf("N: -->");
  511. getInt(&N, 1);
  512. rc = createTree(t, fname, xmin, xmax, ymin, ymax, N);
  513. printf("%s\n", errload[rc]);
  514. }
  515. }
  516.  
  517. int createTree(QTree* t, char* fname, int xmin, int xmax, int ymin, int ymax, int N) {
  518. if (!t) return 1;
  519. //if (!fname) return 2;
  520. if (N < 1) return 3;
  521. if (xmin > xmax) {
  522. printf("Minimal X is greater than maximal one, it\'s interesting... They\'ll be swapped\n");
  523. int tmp = xmin;
  524. xmin = xmax;
  525. xmax = tmp;
  526. }
  527. if (ymin > ymax) {
  528. printf("Minimal Y is greater than maximal one, it\'s interesting... They\'ll be swapped\n");
  529. int tmp = ymin;
  530. ymin = ymax;
  531. ymax = tmp;
  532. }
  533. Node* root = (Node*)malloc(1 * sizeof(Node));
  534. t->root = root;
  535. t->N = N;
  536. t->n = 0;
  537. t->filename = fname;
  538. t->root->xmax = xmax;
  539. t->root->xmin = xmin;
  540. t->root->ymin = ymin;
  541. t->root->ymax = ymax;
  542. t->root->busy = 0;
  543. t->root->itemshead.data = NULL;
  544. t->root->itemshead.next = NULL;
  545. t->root->itemshead.prev = NULL;
  546. t->root->child = NULL;
  547. if (fname) if (load(t, fname)) createFile(t, fname);
  548. //if (!(fopen_s(&(t->fd), fname, "w+b"))) t->root = NULL;
  549. return 0;
  550. }
  551.  
  552. char* makeStr(const char buf[]) {
  553. char *s = (char*)malloc(strlen(buf) + 1);
  554. *s = '\0';
  555. strcat(s, buf);
  556. return s;
  557. }
  558.  
  559. int dialog(const char* msgs[], int N) {
  560. int rc;
  561. do {
  562. for (int i = 0; i < N; ++i) puts(msgs[i]);
  563. puts("Make your choice: --> ");
  564. if (!getInt(&rc, 0)) rc = 0;
  565. if (rc >= 0 && rc < N) continue;
  566. puts("I don't understand you. Please try again.");
  567. } while (rc < 0 || rc >= N);
  568. return rc;
  569. }
  570.  
  571. int getInt(int *t, int mode = -1) {
  572. int r;
  573. do {
  574. r = scanf_s("%d", t);
  575. if (r == 1) {
  576. if (mode == -1) return r;
  577. if (mode == 0) {
  578. if (t >= 0) return r;
  579. else {
  580. printf("Input is incorrect. You should enter a non-negative integer. Try again\n");
  581. scanf_s("%*[^\n]");
  582. continue;
  583. }
  584. }
  585. else if (mode == 1) {
  586. if (t > 0) return r;
  587. else {
  588. printf("Input is incorrect. You should enter a positive integer. Try again\n");
  589. scanf_s("%*[^\n]");
  590. continue;
  591. }
  592. }
  593. else return r;
  594. }
  595. printf("Input is incorrect. You should enter an integer. Try again.\n");
  596. scanf_s("%*[^\n]");
  597. } while (1);
  598. }
  599.  
  600. char *getStr(int mode = 1) {
  601. char *ptr = (char*)malloc(sizeof(char));
  602. char buf[81];
  603. int n, len = 0;
  604. *ptr = '\0';
  605. if (mode) scanf_s("%*c");
  606. do {
  607. n = scanf_s("%80[^\n]", buf, 81);
  608. if (n < 0) {
  609. free(ptr);
  610. ptr = NULL;
  611. continue;
  612. }
  613. if (n == 0) scanf_s("%*c");
  614. else {
  615. len += strlen(buf);
  616. ptr = (char*)realloc(ptr, len + 1);
  617. strcat(ptr, buf);
  618. }
  619. } while (n > 0);
  620. return ptr;
  621. }
  622.  
  623. int main() {
  624. QTree t = { 0, NULL, NULL };
  625. int rc;
  626. if (!dload(&t)) return 1;
  627. while (rc = dialog(msgs, NMsgs)) if (!fptr[rc](&t)) break;
  628. dsave(&t);
  629. puts("Program finished");
  630. fclose(t.fd);
  631. delTree(&t);
  632. return 0;
  633. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement