test_rbtree.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include "rb_tree.h"
  6. typedef struct {
  7. rb_node_t node;
  8. int key;
  9. int value;
  10. } IntIntEntry;
  11. static int cmpfunc(void *x, void *y) {
  12. int *a = x, *b = y;
  13. return *a < *b ? -1 : *a > *b;
  14. }
  15. static void test_largedata();
  16. static int max(int a, int b) { return a > b ? a : b; }
  17. int depth(void *n) {
  18. rb_node_t *node = n;
  19. if (node == NULL) return 0;
  20. return max(depth(node->entry.rbe_left), depth(node->entry.rbe_right)) + 1;
  21. }
  22. int main() {
  23. printf("[TEST] rbtree\n");
  24. rb_tree_t tree = {NULL, cmpfunc, NULL};
  25. IntIntEntry *n;
  26. int a[5] = {1, 2, 3, 4, 5};
  27. for (int i = 0; i < 5; i++) {
  28. n = malloc(sizeof(*n));
  29. n->key = a[i];
  30. n->value = i;
  31. rb_tree_insert(&tree, n);
  32. }
  33. int find = 3;
  34. IntIntEntry *iter;
  35. iter = rb_tree_find(&tree, &find);
  36. assert(iter->key == 3);
  37. rb_tree_remove(&tree, iter);
  38. free(iter);
  39. iter = rb_tree_min(&tree);
  40. int expected[4] = {1, 2, 4, 5};
  41. int i = 0;
  42. for (; iter != NULL; iter = rb_tree_next(&tree, iter)) {
  43. assert(iter->key == expected[i]);
  44. i++;
  45. }
  46. destroy_rb_tree(&tree, NULL);
  47. test_largedata();
  48. printf("[PASS] rbtree\n");
  49. return 0;
  50. }
  51. #define TESTSZ 10000
  52. int input[TESTSZ];
  53. void shuffle(int *input, int n) {
  54. for (int i = n - 1; i > 0; i--) {
  55. int j = rand() % i;
  56. int tmp = input[i];
  57. input[i] = input[j];
  58. input[j] = tmp;
  59. }
  60. }
  61. static void test_largedata() {
  62. // generate random input
  63. time_t t;
  64. srand((unsigned)time(&t));
  65. for (int i = 0; i < TESTSZ; i++) {
  66. input[i] = i;
  67. }
  68. shuffle(input, TESTSZ);
  69. // insert
  70. rb_tree_t tree = {NULL, cmpfunc, NULL};
  71. IntIntEntry *n;
  72. for (int i = 0; i < TESTSZ; i++) {
  73. n = malloc(sizeof(*n));
  74. n->key = input[i];
  75. n->value = input[i];
  76. rb_tree_insert(&tree, n);
  77. }
  78. // check tree validity
  79. int d = depth(tree.rbh_root);
  80. assert(d >= 13 && d <= 28);
  81. IntIntEntry *iter = rb_tree_min(&tree);
  82. int i = 0;
  83. for (; iter != NULL; iter = rb_tree_next(&tree, iter)) {
  84. assert(iter->key == i);
  85. i++;
  86. }
  87. // delete when: key % 3 != 0
  88. memset(input, 0, sizeof(int) * TESTSZ);
  89. int count = 0;
  90. for (int i = 0; i < TESTSZ; i++) {
  91. if (i % 3 != 0) {
  92. input[count] = i;
  93. } else {
  94. continue;
  95. }
  96. count++;
  97. }
  98. shuffle(input, count);
  99. for (int i = 0; i < count; i++) {
  100. IntIntEntry *iter = rb_tree_find(&tree, &input[i]);
  101. assert(iter != NULL);
  102. rb_tree_remove(&tree, iter);
  103. }
  104. // check tree validity
  105. d = depth(tree.rbh_root);
  106. assert(d >= 11 && d <= 24);
  107. iter = rb_tree_min(&tree);
  108. i = 0;
  109. for (; iter != NULL; iter = rb_tree_next(&tree, iter)) {
  110. assert(iter->key == i * 3);
  111. i++;
  112. }
  113. }