搜索二叉树的概念
搜索二叉树满足下面两个要求:
(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 }