Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.26 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <signal.h>
  6. #include <time.h>
  7.  
  8.  
  9.  
  10. unsigned int ns[] = { 10,20,50,100,500,1000,2500,5000,10000,15000,100000};
  11.  
  12. struct node {
  13.     int key;
  14.     struct node *left;
  15.     struct node *right;
  16. };
  17. // tree's beginning is called the root
  18. struct node *root = NULL;
  19.  
  20.  
  21.  struct node **tree_search(struct node **candidate, int value) {
  22.     struct node*temp;
  23.     temp=*candidate;
  24.     if(temp==NULL)
  25.         return candidate;
  26.     if(value < temp->key)
  27.         return tree_search(&temp->left, value);
  28.     if(value > temp->key)
  29.         return tree_search(&temp->right, value);
  30.     return candidate;
  31.  
  32. }
  33.  
  34.  struct node* tree_insert(int value) {
  35.     struct node **nodeptr=tree_search(&root,value);
  36.     struct node *createNode = malloc(sizeof(*createNode));
  37.     (*createNode).key = value;
  38.     (*createNode).left = NULL;
  39.     (*createNode).right = NULL;
  40.     *nodeptr = createNode;
  41. }
  42.  
  43.  
  44.  
  45. struct node **tree_maximum(struct node **candidate) {
  46.     struct node*temp;
  47.     temp=*candidate;
  48.     if(temp->right!=NULL){
  49.         return tree_maximum(&temp->right);
  50.     }
  51.     return candidate;
  52. }
  53.  
  54. void tree_delete(int value) {
  55.     struct node**candidate=tree_search(&root, value);
  56.     struct node*temp=*candidate;
  57.  
  58.     if ((temp->left)==NULL&&(temp->right)==NULL){
  59.         *candidate= NULL;
  60.     }
  61.     else if ((temp->left)!=NULL&&(temp->right)==NULL){
  62.         *candidate=temp->left;
  63.     }
  64.     else if ((temp->left)==NULL&&(temp->right)!=NULL){
  65.         *candidate=temp->right;
  66.     }
  67.     else{
  68.         struct node**maxnodeptr=tree_maximum(&temp->left);
  69.         (temp->key)= ((*maxnodeptr)->key);
  70.         *maxnodeptr=((*maxnodeptr)->left);
  71.     }
  72. }
  73.  
  74. unsigned int tree_size(struct node *element) {
  75.  
  76.     if(element == NULL)
  77.       return 0;
  78.     else
  79.    return( tree_size((element->left) + tree_size(element->right)+1);
  80. }
  81.  
  82.  
  83.  
  84. /*
  85.  * Fill an array with increasing values.
  86.  *
  87.  * Parameters:
  88.  *      int *t:     pointer to the array
  89.  *      int n:      number of elements in the array
  90.  */
  91. void fill_increasing(int *t, int n) {
  92.     for (int i = 0; i < n; i++) {
  93.         t[i] = i;
  94.     }
  95. }
  96.  
  97. /*
  98.  * Reorder array elements in a random way.
  99.  *
  100.  * Parameters:
  101.  *      int *t:     pointer to the array
  102.  *      int n:      number of elements in the array
  103.  */
  104. void shuffle(int *t, int n) {
  105.     for (int i = n - 1; i > 0; i--) {
  106.         int j = rand() % i;
  107.         int temp = t[i];
  108.         t[i] = t[j];
  109.         t[j] = temp;
  110.     }
  111. }
  112.  
  113. /*
  114.  * Check if tree is a valid BST.
  115.  *
  116.  * Parameters:
  117.  *      struct node *element:   pointer to node to be checked
  118.  *
  119.  * Returns:
  120.  *      bool:                   true if subtree rooted in "element" is a BST
  121.  */
  122. bool is_bst(struct node *element) {
  123.     // empty tree is a valid BST
  124.     if (element == NULL) {
  125.         return true;
  126.     }
  127.     // leaf node is valid
  128.     if (element->left == NULL && element->right == NULL) {
  129.         return true;
  130.     }
  131.     // only right subnode? check it recursively
  132.     if (element->left == NULL && element->right != NULL) {
  133.         return (element->key < element->right->key) && is_bst(element->right);
  134.     }
  135.     // only left subnode? check it recursively
  136.     if (element->left != NULL && element->right == NULL) {
  137.         return (element->key > element->left->key) && is_bst(element->left);
  138.     }
  139.     // both subnodes present? check both recursively
  140.     return (element->key > element->left->key)
  141.         && (element->key < element->right->key)
  142.         && is_bst(element->left)
  143.         && is_bst(element->right);
  144. }
  145.  
  146. void insert_increasing(int *t, int n) {
  147.     for (int i = 0; i < n; i++) {
  148.         tree_insert(t[i]);
  149.     }
  150. }
  151.  
  152. void insert_random(int *t, int n) {
  153.     shuffle(t, n);
  154.     for (int i = 0; i < n; i++) {
  155.         tree_insert(t[i]);
  156.     }
  157. }
  158.  
  159. void insert_binary(int *t, int n) {
  160.     // TODO: implement
  161. }
  162.  
  163. char *insert_names[] = { "Increasing", "Random", "Binary" };
  164. void (*insert_functions[])(int*, int) = { insert_increasing, insert_random, insert_binary };
  165.  
  166. int main(int argc, char **argv) {
  167.     for (unsigned int i = 0; i < sizeof(insert_functions) / sizeof(*insert_functions); i++) {
  168.         void (*insert)(int*, int) = insert_functions[i];
  169.  
  170.         for (unsigned int j = 0; j < sizeof(ns) / sizeof(*ns); j++) {
  171.             unsigned int n = ns[j];
  172.  
  173.             // crate an array of increasing integers: 0, 1, 2, ...
  174.             int *t = malloc(n * sizeof(*t));
  175.             fill_increasing(t, n);
  176.  
  177.             // insert data using one of methods
  178.             clock_t insertion_time = clock();
  179.             insert(t, n);
  180.             insertion_time = clock() - insertion_time;
  181.  
  182.             assert(tree_size(root) == n);       // after all insertions, tree size must be `n`
  183.             assert(is_bst(root));               // after all insertions, tree must be valid BST
  184.  
  185.             // reorder array elements before searching
  186.             shuffle(t, n);
  187.  
  188.             // search for every element in the order present in array `t`
  189.             clock_t search_time = clock();
  190.             for (unsigned int k = 0; k < n; k++) {
  191.                 struct node **pnode = tree_search(&root, t[k]);
  192.                 struct node *iter = *pnode;
  193.                 assert(iter != NULL);           // found element cannot be NULL
  194.                 assert(iter->key == t[k]);      // found element must contain the expected value
  195.             }
  196.             search_time = clock() - search_time;
  197.  
  198.             // reorder array elements before deletion
  199.             shuffle(t, n);
  200.  
  201.             // delete every element in the order present in array `t`
  202.             for (unsigned int l = 0, m = n; l < n; l++, m--) {
  203.                 assert(tree_size(root) == m);   // tree size must be equal to the expected value
  204.                 tree_delete(t[l]);
  205.                 assert(is_bst(root));           // after deletion, tree must still be valid BST
  206.             }
  207.             assert(tree_size(root) == 0);       // after all deletions, tree has size zero
  208.  
  209.             free(root);
  210.             free(t);
  211.  
  212.             printf("%d\t%s\t%f\t%f\n",
  213.                     n,
  214.                     insert_names[i],
  215.                     (double)insertion_time / CLOCKS_PER_SEC,
  216.                     (double)search_time / CLOCKS_PER_SEC);
  217.         }
  218.     }
  219.     return 0;
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement