建立二叉搜索树
1.建立树的结构体
<span style="font-size:14px;">struct Tree
{
int data; //数据
Tree *left; //左儿子
Tree *right; //右儿子</span><pre name="code" class="cpp"><span style="font-size:14px;">};</span>
2 . 建立一个空树
(1) 如果你已经有一棵树,那么你可以把该树清空,让它成为一棵空的树。
<span style="font-size:14px;">Tree* MakeEmpty(Tree *T)
{
if(!T)
{
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
}
return NULL;
}</span>
( 2) 建立一棵树. 这里有一个巧妙之处
A.当该树是空树时,这段判断创建一个根存放x。
B.当递归到一个父亲的左儿子(右儿子)为空树,该判断创建一个叶子存放x。
if(T==NULL) //it is about head and new point;
{
T=new Tree;
T->data=x;
T->left=T->right=NULL;
}
<span style="font-size:14px;">Tree* Insert(Tree *T,int x)
{
<span style="color:#ff6666;"> if(T==NULL) //it is about head and new point;
{
T=new Tree;
T->data=x;
T->left=T->right=NULL;
}</span>
else
{
if(x<T->data)
{
T->left=Insert(T->left,x);
}
else if(x>T->data)
{
T->right=Insert(T->right,x);
}
}
return T;
}</span><pre name="code" class="cpp">
3.找值 Find
<span style="font-size:14px;">Tree* Find(Tree *T,int x)
{
if(T==NULL) <span style="color:#ff0000;">//判断该树是否为空</span>
{
return NULL;
}
else
{
if(x<T->data) </span><span style="color: rgb(255, 0, 0); font-size: 14px; font-family: Arial, Helvetica, sans-serif;">//从X是否大于判断父节点,判断X在该父节点的左边还是右边。</span><span style="font-size:14px;">
{
return Find(T->left,x);
}
else if(x>T->data)
{
return Find(T->right,x);
}
else <span style="color:#ff0000;">//当X不大于也不小于父节点的时候,该节点的值就是要找的值,直接return 该节点。</span>
{
return T; </span>
}
}
}
4.找到最小值 FindMax (递归)
<span style="font-size:14px;">Tree* FindMin(Tree *T) <span style="color:#ff0000;">//用递归的方式去寻找最小值</span>
{
if(T==NULL)
{
return NULL;
}
else
{
if(T->left!=NULL)
{
<span style="color:#ff0000;">return FindMin(T->left);</span>
}
else
{
return T;
}
}
}</span>
5.找到最大值 (while)
<span style="font-size:14px;">Tree* FindMax(Tree *T)
{
if(T==NULL)
{
return NULL;
}
while(!(T->right)) <span style="color:#ff0000;"> // !T->right 等值于 T->right != NULL</span>
{
T=T->right;
}
return T;
}</span>
6.删除Delete(难点)
A. 该处有个难点。当找到X所在的节点,但该节点有二个孩子的时候。
思路:取右节点中的最小值代替该节点,并删除这个最小值。
想法:调用FindMin函数找到最小值后,要删除最小值,就应该调用Delete函数(相当于把右儿子看成一个新的树,最小值为X).
但要注意的是:连接问题。被代替的父节点跟右儿子的连接。(不要忘记)(
T->right=Delete(T->right,p->data)
)
)
<span style="font-size:14px;">Tree* Delete(Tree *T, int x)
{
Tree *p;
if(T==NULL) <span style="color:#ff0000;"> //判断是否为空根</span>
{
return NULL;
}
if(x<T->data) <span style="color:#ff0000;">//判断X在父节点左边还是右边</span>
{
T->left=Delete(T->left,x);
}
else if(x>T->data)
{
T->right=Delete(T->right,x);
}
else <span style="color:#ff0000;">//接下来判断该节点有多小个孩子。</span>
{
if(T->left&&T->right) <span style="color:#ff0000;">// have tow child (有两个儿子,所以取右儿子中的最小值来代替父节点)</span>
{
p=FindMin(T->right);
T->data=p->data;
<span style="color:#ff0000;">T->right=Delete(T->right,p->data);</span>
}
else <span style="color:#ff0000;">//only one chile or none (因为只有一个节点或无,所以直接取该儿子代替父节点,或直接删 除该节点)</span>
{
p=T;
if(T->left==NULL)
{
T=T->right;
}
else if(T->right==NULL)
{
T=T->left;
}
free(p);
}
}
return T;
}</span>