zoukankan      html  css  js  c++  java
  • 二叉排序树删除、搜索、插入的递归实现

      #返回上一级

    @Author: 张海拔

    @Update: 2014-01-17

    @Link: http://www.cnblogs.com/zhanghaiba/p/3524079.html

    二叉排序树本身就是递归定义的,用递归实现还是挺简单的。迭代实现见 “二叉排序树删除、搜索、插入的迭代实现 link(public)

    #插入操作:

    若树根为空则返回一个新节点,

    否则若item < root->item,则到左子树中去插入;若item > root->item,则到右子树去插入,若item == root->item,则忽略;插入完毕后返回树根。

    #删除操作:

    若树根为空返回NULL,删除过程伴随着搜索,如果找不到待删节点,则搜索到边界(当前树根为空)时,删除空树应该返回NULL。

    否则,若item < root->item,则到左子树去删除;若item > root->item,则到右子树去删除;若item == root->item,说明找到了待删除的节点D。

    此时有三种情况:

    1)若D节点有左孩子

    想象D放在BST中序遍历序列(从小到大的序列)中,而D的直接前驱必定是D的左子树里面值最大的那个节点,设为C。

    找到C之后,让C和D交换值,此时问题转换为删除C

    因为马上要删除C,所以C的值没必要修改。注意C的特征是一定不存在右孩子(左孩子可能存在),这意味这C的直接前驱就是C的左孩子

    删除C则递归地删除C的左孩子,左孩子可能是C节点也可能是E节点(见情况2),所以

    直到当前C(或当前E)的左(右)孩子为空即C(E)成为叶子,此时删除叶子C(E)则归结为情况3),所以情况3)是递归出口(终止条件)。

    2)若D节点没有左孩子但有右孩子,与情况1)的分析是对称的,故略。(设D的直接后继为E

    3)若D节点是叶子,则直接删除它。(释放空间并使之指向NULL)

    删除完毕后返回树根。

     

    #搜索操作:

    若树根是空则返回NULL。

    若item < root->item,返回搜索左子树的搜索结果;若item > root->item,返回搜索右子树的搜索结果;若item == root->item,则直接返回root。

    root是指向关键字节点的指针。显然找不到时(找到边界了),当前树根是空,归结为第一种情况返回NULL。

    上述实现中——

    (1)如果要可视化BST(打印出成一棵树),需要装一个Greg Lee编写的tree模块,主要是用Lex/Flex写成的开源小工具。

    Linux用户直接make即可。Mac用户编译时先修改Makefile,把Lex改为Flex,再make即可。

    这个模块软件的安装包google搜索"Greg Lee tree"即可找到,用法参见下载页面的说明或源代码中的README。

    上述程序中,生成的tree_src.txt与本程序在同一目录,要确保有写、删权限,其次我的tree在~/tree/tree中,所以外部命令调用的是"cat ./tree_src.txt | ~/tree/tree"

    fopen要支持覆盖写入比较啰嗦,所以在打开tree_src.txt前先执行强制删除该文件的外部命令(因为如果没有该文件也是不会报错的)。

    (2)对于BST:插入操作,如果重复则忽略;删除操作,如果没有该项则也忽略;只有搜索操作做得相对完善。

    (3)命令行用户手册:

    "i 432" (insert) 即删除值为423的项目(元素), "d 432"(delele) 和 "s 432"(search)类似

    "l" (list) 列出BST的中序遍历序列

    "p" (print by tree) 使用tree模块可视化/打印出BST

    "q" (quit) 退出程序

    下面是二叉排序树删除、搜索和插入的完整递归实现,以及一个测试示范。

      1 /*
      2  *Author: ZhangHaiba
      3  *Date: 2014-1-16
      4  *File: binary_search_tree_rec.c
      5  *
      6  *this demo shows how to build a BST data structure
      7  *and support some command line to operate this BST 
      8  *such like i(insert), d(delete), s(search), q(quit) etc
      9  *interestingly, this demo use tree module which written by Greg Lee
     10  *making BST data structure and it's opreation visualization
     11  *
     12  *hint: implementation recusive
     13  */
     14 
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <stdbool.h>
     18 #define MOD 256
     19 #define CMD_LEN 128
     20 
     21 typedef struct node* link;
     22 
     23 typedef struct node {
     24     int item;
     25     link left;
     26     link right;
     27 }node;
     28 
     29 
     30 //public
     31 link NODE(int item, link left, link right); //as constructor
     32 link bst_insert(link root, int item);
     33 link bst_delete(link root, int item);
     34 link bst_search(link root, int item);
     35 void bst_inorder(link root);
     36 void bst_show_by_tree(link root);
     37 //private
     38 link pre(link root);
     39 link next(link root);
     40 void inorder(link root); //included in bst_inorder()
     41 void tree_print(link root, FILE* fd); //included in bst_show_by_tree()
     42 
     43 int main(void)
     44 {
     45 
     46     link r = NULL; //BST root
     47 
     48     //operating this the BST r
     49 
     50             /*** Command Line Manual ***/
     51     /* 
     52      * "i 100" means insert item which value 100
     53      * "d 200" means delete item which value 200
     54      * "s 300" means search item which value 300
     55      * "p" means call the tree module to print the BST tree
     56      * "l" means list the inorder list of BST 
     57      * "q" means quit
     58      */
     59 
     60     while (true) {
     61         char cmd[CMD_LEN];
     62 
     63         scanf("%s", cmd);
     64         if (cmd[0] == 'q')
     65             break;
     66         else if (cmd[0] == 'i' || cmd[0] == 'd' || cmd[0] == 's') {
     67             int item;
     68             scanf("%d", &item);
     69             if (cmd[0] == 'i')
     70                 r = bst_insert(r, item);
     71             else if (cmd[0] == 'd')
     72                 r = bst_delete(r, item);
     73             else {
     74                 link aim_link = bst_search(r, item);
     75                 if (aim_link == NULL)
     76                     printf("Not Found!
    ");
     77                 else
     78                     printf("Found: %d
    ", aim_link->item);
     79             }
     80         }
     81         else if (cmd[0] == 'p')
     82             bst_show_by_tree(r);
     83         else if (cmd[0] == 'l')
     84             bst_inorder(r);
     85         else
     86             ; //ingnore illegal command line
     87     }
     88     return 0;
     89 }
     90 
     91 link NODE(int item, link left, link right)
     92 {
     93     link born = malloc(sizeof (node));
     94     born->item = item;
     95     born->left = left;
     96     born->right = right;
     97     return born;
     98 }
     99 
    100 link bst_insert(link root, int item)
    101 {
    102     if (root == NULL)
    103         return NODE(item, NULL, NULL);
    104     else if(item < root->item)
    105         root->left = bst_insert(root->left, item);
    106     else if(item > root->item)
    107         root->right = bst_insert(root->right, item);
    108     else
    109         ; //ignored the repeating item;
    110     return root;
    111 }
    112 
    113 link bst_delete(link root, int item)
    114 {
    115     if (root == NULL)
    116         return NULL;
    117     else if (item < root->item)
    118         root->left = bst_delete(root->left, item);
    119     else if (item > root->item)
    120         root->right = bst_delete(root->right, item);
    121     else {
    122         if (root->left != NULL)
    123             root->left = bst_delete(root->left, root->item = pre(root)->item);
    124         else if (root->right != NULL)
    125             root->right = bst_delete(root->right, root->item = next(root)->item);
    126         else {
    127             free(root);
    128             root = NULL;
    129         }
    130     }
    131     return root;
    132 }
    133 
    134 link bst_search(link root, int item)
    135 {
    136     if (root == NULL)
    137         return NULL;
    138     else if (item < root->item)
    139         return bst_search(root->left, item);
    140     else if (item > root->item)
    141         return bst_search(root->right, item);
    142     else
    143         return root;
    144 }
    145 
    146 //has grantee root != NULL
    147 link pre(link root)
    148 {
    149     link p = root->left;
    150 
    151     while (p->right != NULL)
    152         p = p->right;
    153     return p;
    154 }
    155 
    156 //has grantee root != NULL
    157 link next(link root)
    158 {
    159     link p = root->right;
    160 
    161     while (p->left != NULL)
    162         p = p->left;
    163     return p;
    164 }
    165 
    166 void bst_inorder(link root)
    167 {
    168     inorder(root);
    169     printf("
    ");
    170 }
    171 
    172 void inorder(link root)
    173 {
    174     if (root == NULL)        
    175         return;
    176     inorder(root->left);
    177     printf("%d ", root->item);
    178     inorder(root->right);    
    179 }
    180 
    181 void bst_show_by_tree(link root)
    182 {
    183     char cmd[CMD_LEN];
    184 
    185     sprintf(cmd, "rm -f ./tree_src.txt");
    186     system(cmd);
    187 
    188     FILE *fd = fopen("./tree_src.txt", "a+");
    189     fprintf(fd, "
    	\tree");
    190     tree_print(root, fd);
    191     fprintf(fd, "
    
    ");
    192     fclose(fd);
    193 
    194     sprintf(cmd, "cat ./tree_src.txt | ~/tree/tree");
    195     system(cmd);
    196 }
    197 
    198 void tree_print(link root, FILE *fd)
    199 {    
    200     fprintf(fd, "(");
    201     if (root != NULL) {
    202         fprintf(fd, "%d", root->item);
    203         tree_print(root->left, fd);
    204         tree_print(root->right, fd);
    205     }
    206     fprintf(fd, ")");
    207 }

    测试示范

    ZhangHaiba-MacBook-Pro:code apple$ ./a.out
    i 432
    p
    
            432
            _|__
            |  |
    
    i 234 i 526
    p
    
               432
             ___|___
             |     |
            234   526
            _|__  _|__
            |  |  |  |
    
    i 43 i 632 i 535 i 333 i 13 i 53 i 35
    l
    13 35 43 53 234 333 432 526 535 632 
    p
    
                      432
                   ____|____
                   |       |
                  234     526
                ___|____  _|__
                |      |  |  |
                43    333   632
             ___|___  _|__  _|__
             |     |  |  |  |  |
             13    53      535
            _|__  _|__     _|__
            |  |  |  |     |  |
               35
              _|__
              |  |
    
    d 35
    p
    
                      432
                   ____|____
                   |       |
                  234     526
                ___|____  _|__
                |      |  |  |
                43    333   632
             ___|___  _|__  _|__
             |     |  |  |  |  |
             13    53      535
            _|__  _|__     _|__
            |  |  |  |     |  |
    
    d 634
    p
    
                      432
                   ____|____
                   |       |
                  234     526
                ___|____  _|__
                |      |  |  |
                43    333   632
             ___|___  _|__  _|__
             |     |  |  |  |  |
             13    53      535
            _|__  _|__     _|__
            |  |  |  |     |  |
    
    l
    13 43 53 234 333 432 526 535 632 
    d 432 
    p
    
                   333
                 ___|____
                 |      |
                234    526
                _|__  __|__
                |  |  |   |
                43       632
             ___|___     _|__
             |     |     |  |
             13    53   535
            _|__  _|__  _|__
            |  |  |  |  |  |
    
    d 234
    p
    
                 333
               ___|___
               |     |
               53   526
              _|__  _|__
              |  |  |  |
              43      632
             _|__     _|__
             |  |     |  |
             13      535
            _|__     _|__
            |  |     |  |
    
    s 33
    Not Found!
    s 13
    Found: 13
    s 526
    Found: 526
    s 334
    Not Found!
    i 444
    p
    
                  333
               ____|____
               |       |
               53     526
              _|__  ___|___
              |  |  |     |
              43   444   632
             _|__  _|__  _|__
             |  |  |  |  |  |
             13         535
            _|__        _|__
            |  |        |  |
    
    d 53
    l
    13 43 333 444 526 535 632 
    p
    
                 333
              ____|____
              |       |
              43     526
             _|__  ___|___
             |  |  |     |
             13   444   632
            _|__  _|__  _|__
            |  |  |  |  |  |
                       535
                       _|__
                       |  |
    
    d 632
    p
    
                 333
              ____|____
              |       |
              43     526
             _|__  ___|___
             |  |  |     |
             13   444   535
            _|__  _|__  _|__
            |  |  |  |  |  |
    
    q

      #返回上一级

  • 相关阅读:
    058_从键盘读取一个论坛积分,判断论坛用户等级
    057_统计 Linux 进程相关数量信息
    bzoj3436
    bzoj1202
    bzoj1044
    bzoj2338
    bzoj1854
    bzoj1856
    830C
    bzoj2132
  • 原文地址:https://www.cnblogs.com/zhanghaiba/p/3524079.html
Copyright © 2011-2022 走看看