• 22.0、C语言数据结构——二叉排序树


    22.0、C语言数据结构——二叉排序树

    二叉排序树(Binary Sort Tree)又称为二叉查找树,他可以是一棵空树,或者具有下列性质 ->

            - 若他的左子树不为空,则左子树上所有结点的值均小于他的根结点的值;

            - 若他的右子树不为空,则左子树上所有结点的值均大于他的根结点的值;

            - 他的左、右子树也分别为二叉排序树(可用递归的方式实现)

    增加、删除、查询代码如下->

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. #include
    5. #include
    6. typedef struct Node {
    7. int data;
    8. struct Node* lchild;
    9. struct Node* rchild;
    10. }Node;
    11. typedef struct BinaryTree {
    12. Node* rNode;
    13. int num;
    14. }Tree;
    15. //初始化根结点
    16. void InitRootNode(Tree* tree) {
    17. int rootData = 0;
    18. scanf("%d",&rootData);
    19. Node* tmp = (Node*)malloc(sizeof(Node));
    20. assert(tmp != NULL);
    21. tmp->data = rootData;
    22. tmp->lchild = NULL;
    23. tmp->rchild = NULL;
    24. tree->rNode = tmp;
    25. tree->num = 1;
    26. }
    27. //添加结点
    28. void addTreeNode(Tree* tree) {
    29. Node* tmp = (Node*)malloc(sizeof(Node));
    30. assert(tmp != NULL);
    31. int newNodeData = 0;
    32. scanf("%d",&newNodeData);
    33. tmp->data = newNodeData;
    34. tmp->lchild = NULL;
    35. tmp->rchild = NULL;
    36. Node* tmp2 = tree->rNode;
    37. while(1) {
    38. if (newNodeData > tmp2->data) {
    39. if (tmp2->rchild == NULL) {
    40. tmp2->rchild = tmp;
    41. tree->num++;
    42. break;
    43. }
    44. tmp2 = tmp2->rchild;
    45. }
    46. else {
    47. if (tmp2->lchild == NULL) {
    48. tmp2->lchild = tmp;
    49. tree->num++;
    50. break;
    51. }
    52. tmp2 = tmp2->lchild;
    53. }
    54. }
    55. }
    56. //结点查找
    57. int searchTreeNode(Tree* tree,int data) {
    58. Node* tmp = tree->rNode;
    59. while (tmp != NULL) {
    60. if (data == tmp->data) {
    61. return 1;
    62. }
    63. else if (data > tmp->data) {
    64. tmp = tmp->rchild;
    65. }
    66. else if (data < tmp->data) {
    67. tmp = tmp->lchild;
    68. }
    69. }
    70. return 0;
    71. }
    72. //结点删除
    73. int deleteTreeNode(Tree* tree,int key) {
    74. Node* tmp = tree->rNode;
    75. if (!tree) {
    76. return 0;
    77. }
    78. else {
    79. if (key == tmp->data) {
    80. return Delete(tree);
    81. }
    82. else if (key < tmp->data) {
    83. return deleteTreeNode(tmp->lchild,key);
    84. }
    85. else {
    86. return deleteTreeNode(tmp->rchild, key);
    87. }
    88. }
    89. }
    90. int Delete(Tree* tree) {
    91. Node* q;
    92. Node* s;
    93. Node* p = tree->rNode;
    94. if (q->rchild == NULL) {
    95. q = p;
    96. p = p->lchild;
    97. free(q);
    98. }
    99. else if (p->lchild == NULL) {
    100. q = p;
    101. p = p->rchild;
    102. free(q);
    103. }
    104. else {
    105. q = p;
    106. s = p->lchild;
    107. while (s->rchild) {
    108. q = s;
    109. s = s->rchild;
    110. }
    111. p->data = s->data;
    112. if (q != p) {
    113. q->rchild = s->lchild;
    114. }
    115. else {
    116. q->lchild = s->lchild;
    117. }
    118. free(s);
    119. }
    120. return 1;
    121. }
    122. int main() {
    123. return 0;
    124. }

    这里主要说一下删除结点的步骤 ->

            1. 待删除的结点只有左子树或者只有右子树的情况下,我们只需要将该结点的子树接到待删除的父结点处即可;

            2. 待删除的结点是叶子结点,直接删除即可;

            3. 待删除的结点既有左子树也有右子树,将该二叉树进行中序遍历,得到待删除结点的前驱接点或者后继结点,将待删除结点的值替换成 -> 前驱结点的值或后继结点的值,这里就先讨论前驱结点这一种情况),再将前驱结点的父结点指向前驱结点的左子树,最后将前驱结点的空间释放掉即可;
            (如果是将待删除结点的值替换成 -> 后继结点的值,就将后继结点的父结点指向后继结点的右子树,最后将后继结点的空间释放掉即可)

    结点的添加、遍历 ->

            如果待添加的结点的值比根结点小放根结点左边,反之放右边,然后依次往下走小的放左边大的放右边,直到遍历至可存放的位置将新结点结存放进去即可;

            遍历查找结点也是一样,从根结点开始比较,待查找的结点比该结点大就往右走,反之往左走,直到查找到该结点然后返回,如果查找至 NULL 还未找到就是查找失败了;

  • 相关阅读:
    [LeetCode/力扣][Java] 0315. 计算右侧小于当前元素的个数(Count of Smaller Numbers After Self)
    add_precompiled_header
    Libuv源码解析 - uv_loop整个初始化模块
    雷达散射截面(RCS)相关概念
    js 面向对象
    Tcache Stashing Unlink Attack 原理详解
    macOS三种软件安装目录以及环境变量优先级
    贪心算法--找换硬币
    设计模式-拦截过滤器模式
    Python 对象表现得像函数
  • 原文地址:https://blog.csdn.net/m0_52433668/article/details/127426982