1. 程式人生 > >搜尋二叉樹的查詢,插入,刪除遞迴實現

搜尋二叉樹的查詢,插入,刪除遞迴實現

搜尋二叉樹的概念

    搜尋二叉樹滿足下面兩個要求:

(1)它是一棵二叉樹

(2)該二叉樹中,任意一棵樹的根節點值大於它左子樹中的所有結點的值,小於右子樹中的所有結點的值

因此對於搜尋二叉樹的中序遍歷來說,它是按由小到大依次遞增的順序排列的。

1. 搜尋二叉樹的表示

  3 //定義搜尋二叉樹的節點結構/孩子表示法
  4 typedef char SearchTreeType;
  5 typedef struct SearchTreeNode
  6 {
  7     SearchTreeType data;
  8     struct SearchTreeNode*lchild;                                                                                                                                  
  9
struct SearchTreeNode*rchild; 10 }SearchTreeNode;

2. 搜尋二叉樹的初始化

 12 //初始化二叉搜尋樹
 13 void SearchTreeInit(SearchTreeNode** proot)
 14 {
 15     if(proot==NULL)
 16     {
 17         return ;
 18     }
 19     *proot=NULL;
 20     return ;
 21 }

3.二叉搜尋樹插入元素

插入元素後要保證依然滿足二叉搜尋樹,該結點所在的位置應當是固定的。

首先插入元素應作為某個節點的左孩子或右孩子。如果作為左孩子,則該結點的左
子樹必須為空,如果作為右孩子,則該節點的右子樹必須為空。

作為右子樹還是左子樹,應根據插入元素與該結點的值進行大小判斷,如果指定元素小於該結點的值,則作為該結點的左子樹,如果大於,則作為該結點的右子樹。

 23 //二叉搜尋樹插入元素(遞迴)
 24 void SearchTreeInsert(SearchTreeNode**proot, SearchTreeType value)
 25 {
 26     if(proot==NULL)
 27     {
 28         return ;
 29     }
 30     SearchTreeNode* ne_node=CreateNode(value);
 1     //根節點為空  
32 if(*proot==NULL) 33 { 34 *proot=new_node; 35 return ; 36 } 37 // 根節點不為空 38 //如果插入元素小於根節點,遞迴插入左子樹 39 if(value<(*proot)->data) 40 { 41 SearchTreeInsert(&(*proot)->lchild,value); 42 } 43 //如果插入元素大於根節點,遞迴插入右子樹 44 else if(value>(*proot)->data) 45 { 46 SearchTreeInsert(&(*proot)->rchild,value); 47 } 48 else //如果插入元素等於根節點 49 { 50 //約定二叉樹不允許相等的節點 51 //所以不做處理 52 return ; 53 } 54 return ; 55 }

4.搜尋二叉樹的查詢

 57 //搜尋二叉樹的查詢(遞迴)
 58 SearchNode* SearchTreeFind(SearchTreeNode* root, SearchTreeType to_find)
 59 {
 60     if(root==NULL)
 61     {
 62         //非法輸入
 63         return ;
 64     }
 65     //如果找到了直接返回
 66     if(root->data==to_find)
 67     {
 68         return root; 
 69     }
 70     //如果查詢值小於根節點,左子樹遞迴查詢
 71     else if(to_find<root->data)
 72     {
 73         return SearchTreeFind(&root->lchild,to_find);
 74     }
 75     //如果查詢值大於根節點,右子樹遞迴查詢
 76     else
 77     {
 78         return SearchTreeFind(&root->rchild,to_find);
 79     }                                                                                                                                                              
 80 }

5.二叉搜尋樹的刪除
首先查詢待刪元素是否在二叉搜尋樹中
如果待刪元素小於根節點,在左子樹中遞迴查詢
如果待刪元素大於根節點,在右子樹中遞迴查詢
a.要刪除的節點無孩子
b.要刪除的節點只有左孩子
c.要刪除的節點只有右孩子
d.要刪除的節點有左,右孩子節點

 82 //搜尋二叉樹的刪除(遞迴)
 83 void SearchTreeRemove(SearchTreeNode** proot, SearchTreeType to_remove )
 84 {
 85     if(proot==NULL)
 86     {
 87         return ;
 88     }
 89     if(*proot==NULL)
 90     {
 91         return ;
 92     }
 93 
 94     SearchTreeNode* cur=*proot;
 95     //如果待刪除值小於根節點,在左子樹遞迴查詢
 96     if(to_remove<cur->data)
 97     {
 98         SearchTreeRemove(&cur->lchild,to_remove);
 99     }
100     //如果待刪除值大於根節點,在右子樹遞迴查詢
101     else if(to_remove>cur->data)
102     {
103         SearchTreeRemove(&cur->rchild,to_remove);
104     }
105     //找到了
106     else
107     {
108         //要刪除的節點沒孩子
109         if(cur->lchild==NULL&&cur->rchild==NULL)
110         {
111             *proot==NULL;
112             DestroyNode(cur);
113         }
114         //要刪除的節點只有左孩子
115         else if(cur->lchild!=NULL&&cur->rchild==NULL)
116         {
117             *proot=cur->lchild;
118             DestroyNode(cur);
119         }
120         //要刪除的節點只有右孩子
121         else if(cur->lchild==NULL&&cur->rchild!=NULL)
122         {
123             *proot==cur->rchild;
124             DestroyNode(cur);
125         }
126         //要刪除的節點有左右孩子
127         else
128         {
129             //在右子樹中查詢最小值,將值賦給要刪除的節點
130             SearchTreeNode* min=cur->rhicld;
131             while(min->rchild!=NULL)
132             {
133                 min=min->rchild;
134 
135             }
136             cur->data=min->data;
137             //遞迴刪除最小值
138            SearchTreeRemove(&cur->rchild,min->data);
139         }
140     }
141     return ;
142 }