搜尋二叉樹的查詢,插入,刪除遞迴實現
阿新 • • 發佈:2018-12-24
搜尋二叉樹的概念
搜尋二叉樹滿足下面兩個要求:
(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 }