bitree.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "bitree.h"
  2. #include <mm/slab.h>
  3. #include <common/errno.h>
  4. #include <debug/bug.h>
  5. #define smaller(root, a, b) (root->cmp((a)->value, (b)->value) == -1)
  6. #define equal(root, a, b) (root->cmp((a)->value, (b)->value) == 0)
  7. #define greater(root, a, b) (root->cmp((a)->value, (b)->value) == 1)
  8. /**
  9. * @brief 创建二叉搜索树
  10. *
  11. * @param node 根节点
  12. * @param cmp 比较函数
  13. * @param release 用来释放结点的value的函数
  14. * @return struct bt_root_t* 树根结构体
  15. */
  16. struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value))
  17. {
  18. if (node == NULL || cmp == NULL)
  19. return -EINVAL;
  20. struct bt_root_t *root = (struct bt_root_t *)kmalloc(sizeof(struct bt_root_t), 0);
  21. memset((void *)root, 0, sizeof(struct bt_root_t));
  22. root->bt_node = node;
  23. root->cmp = cmp;
  24. root->release = release;
  25. root->size = (node == NULL) ? 0 : 1;
  26. return root;
  27. }
  28. /**
  29. * @brief 创建结点
  30. *
  31. * @param left 左子节点
  32. * @param right 右子节点
  33. * @param value 当前节点的值
  34. * @return struct bt_node_t*
  35. */
  36. struct bt_node_t *bt_create_node(struct bt_node_t *left, struct bt_node_t *right, struct bt_node_t *parent, void *value)
  37. {
  38. struct bt_node_t *node = (struct bt_node_t *)kmalloc(sizeof(struct bt_node_t), 0);
  39. FAIL_ON_TO(node == NULL, nomem);
  40. memset((void *)node, 0, sizeof(struct bt_node_t));
  41. node->left = left;
  42. node->right = right;
  43. node->value = value;
  44. node->parent = parent;
  45. return node;
  46. nomem:;
  47. return -ENOMEM;
  48. }
  49. /**
  50. * @brief 插入结点
  51. *
  52. * @param root 树根结点
  53. * @param value 待插入结点的值
  54. * @return int 返回码
  55. */
  56. int bt_insert(struct bt_root_t *root, void *value)
  57. {
  58. if (root == NULL)
  59. return -EINVAL;
  60. struct bt_node_t *this_node = root->bt_node;
  61. struct bt_node_t *last_node = NULL;
  62. struct bt_node_t *insert_node = bt_create_node(NULL, NULL, NULL, value);
  63. FAIL_ON_TO((uint64_t)insert_node == (uint64_t)(-ENOMEM), failed);
  64. while (this_node != NULL)
  65. {
  66. last_node = this_node;
  67. if (smaller(root, insert_node, this_node))
  68. this_node = this_node->left;
  69. else
  70. this_node = this_node->right;
  71. }
  72. insert_node->parent = last_node;
  73. if (unlikely(last_node == NULL))
  74. root->bt_node = insert_node;
  75. else
  76. {
  77. if (smaller(root, insert_node, last_node))
  78. last_node->left = insert_node;
  79. else
  80. last_node->right = insert_node;
  81. }
  82. ++root->size;
  83. return 0;
  84. failed:;
  85. return -ENOMEM;
  86. }
  87. /**
  88. * @brief 搜索值为value的结点
  89. *
  90. * @param value 值
  91. * @param ret_addr 返回的结点基地址
  92. * @return int 错误码
  93. */
  94. int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr)
  95. {
  96. struct bt_node_t *this_node = root->bt_node;
  97. struct bt_node_t tmp_node = {0};
  98. tmp_node.value = value;
  99. // 如果返回地址为0
  100. if (ret_addr == NULL)
  101. return -EINVAL;
  102. while (this_node != NULL && !equal(root, this_node, &tmp_node))
  103. {
  104. if (smaller(root, &tmp_node, this_node))
  105. this_node = this_node->left;
  106. else
  107. this_node = this_node->right;
  108. }
  109. if (this_node != NULL && equal(root, this_node, &tmp_node))
  110. {
  111. *ret_addr = (uint64_t)this_node;
  112. return 0;
  113. }
  114. else
  115. {
  116. // 找不到则返回-1,且addr设为0
  117. *ret_addr = NULL;
  118. return -1;
  119. }
  120. }
  121. static struct bt_node_t *bt_get_minimum(struct bt_node_t *this_node)
  122. {
  123. while (this_node->left != NULL)
  124. this_node = this_node->left;
  125. return this_node;
  126. }
  127. /**
  128. * @brief 删除结点
  129. *
  130. * @param root 树根
  131. * @param value 待删除结点的值
  132. * @return int 返回码
  133. */
  134. int bt_delete(struct bt_root_t *root, void *value)
  135. {
  136. uint64_t tmp_addr;
  137. int retval;
  138. // 寻找待删除结点
  139. retval = bt_query(root, value, &tmp_addr);
  140. if (retval != 0 || tmp_addr == NULL)
  141. return retval;
  142. struct bt_node_t *this_node = (struct bt_node_t *)tmp_addr;
  143. struct bt_node_t *to_delete = NULL, *to_delete_son = NULL;
  144. if (this_node->left == NULL || this_node->right == NULL)
  145. to_delete = this_node;
  146. else
  147. {
  148. to_delete = bt_get_minimum(this_node->right);
  149. // 释放要被删除的值,并把下一个结点的值替换上来
  150. root->release(this_node->value);
  151. this_node->value = to_delete->value;
  152. }
  153. if (to_delete->left != NULL)
  154. to_delete_son = to_delete->left;
  155. else
  156. to_delete_son = to_delete->right;
  157. if (to_delete_son != NULL)
  158. to_delete_son->parent = to_delete->parent;
  159. if (to_delete->parent == NULL)
  160. root->bt_node = to_delete_son;
  161. else
  162. {
  163. if (to_delete->parent->left == to_delete)
  164. to_delete->parent->left = to_delete_son;
  165. else
  166. to_delete->parent->right = to_delete_son;
  167. }
  168. --root->size;
  169. // 释放最终要删除的结点的对象
  170. kfree(to_delete);
  171. }
  172. /**
  173. * @brief 释放整个二叉搜索树
  174. *
  175. * @param root 树的根节点
  176. * @return int 错误码
  177. */
  178. int bt_destroy_tree(struct bt_root_t *root)
  179. {
  180. // todo: 待kfifo完成后,使用kfifo队列来辅助destroy
  181. return -1;
  182. }