二叉排序樹刪除、搜索、插入的遞歸實現

  #返回上一級
html

@Author: 張海拔node

@Update: 2014-01-17app

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

 

二叉排序樹自己就是遞歸定義的,用遞歸實現仍是挺簡單的。迭代實現見 「二叉排序樹刪除、搜索、插入的迭代實現 link(public)測試

#插入操做:ui

若樹根爲空則返回一個新節點,this

不然若item < root->item,則到左子樹中去插入;若item > root->item,則到右子樹去插入,若item == root->item,則忽略;插入完畢後返回樹根。google

 

#刪除操做:spa

若樹根爲空返回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!\n");
 77                 else
 78                     printf("Found: %d\n", 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("\n");
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, "\n\t\\tree");
190     tree_print(root, fd);
191     fprintf(fd, "\n\n");
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

 

  #返回上一級

相關文章
相關標籤/搜索