1. 查找树的创建(createTree)
假设有如下数组4,1,45,78,345,23,12,3,6,21
首先选定4为root,然后遍历剩下的数字,如果大于等于4则放到4的右侧,小于4放到4的左侧,最后构建成的树:所有的左孩子都小于父节点,所有的右孩子都大于等于父节点。如下图:
2. 遍历查找树(displayTree)
按照左中右的顺序遍历树,结果为:1,3,4,5,12,21,23,45,78,345,遍历的结果就是已经排好序的数字。
3. 查找树中的节点(searchTree)
从根节点开始,如果大于等于根节点,则查找根节点的右侧;如果小于根节点,则查找根节点的左侧,直到查找到节点。
比如要查找12:
比4大,往右走;
比45小,往左走;
比23小,往左走;
找到12
4. 删除树中的节点(deleteNode)
这个是最复杂的,因为删除完节点后要重新构建树,涉及到的情况很多:
a.要删除的node没有左右孩子,有父节点。
如果要删除的node为父节点的左孩子,则将父节点的左孩子指针设置为NULL;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为NULL。最后删除node。
b.要删除的node没有左右孩子,没有父节点(即根节点)。
根节点设为NULL,删除node。
c.要删除的node有左孩子没右孩子,有父节点
如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。
d.要被删除的node有左孩子没有右孩子,没有父节点
将要被删除的node的左孩子设置为根节点,删除node。
e.要删除的node有右孩子没左孩子,有父节点
如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的右孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的右孩子。最后删除node。
f.要被删除的node有右孩子没有左孩子,没有父节点
将要被删除的node的右孩子设置为根节点,删除node。
g.要被删除的node左右孩子都有,有父节点
将要被删除node的右孩子插入到左孩子中去。如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。
h.要被删除的node左右孩子都有,无父节点
将要被删除node的右孩子插入到左孩子中去,父节点修改为要被删除node的左孩子,删除node
-------------------------------------------------------------------------------------------------------------------------------------------------------------
//关于二叉查找树的算法
#include <cstdio>
#include <cstdlib>
//#define _OJ_
typedef struct tree
{
int data;
struct tree *lchild;
struct tree *rchild;
} tree, *Bitree;
Bitree
Find_x(Bitree T, int x)
{
if(T == NULL) {
printf("没有找到!\n"); return NULL;}
if(T->data < x) Find_x(T->rchild, x);
else if(T->data > x) Find_x(T->lchild, x);
else return T;
}//递归查找元素没找到则返回null包括根节点返回null代表没有找到
Bitree
Find_min(Bitree T)
{
if(T->lchild == NULL) return T;
else T->lchild = Find_min(T->lchild);
}
//找最大的元素和最小元素递归与非递归的写法
Bitree
Find_max(Bitree T)
{
while (T->rchild != NULL)
{T = T->rchild; printf("%d\n", T->data);}
return T;
}
Bitree
Insert_elem(Bitree T, int x)
{
if(T == NULL) {
T = (Bitree) malloc (sizeof(tree));
T->lchild = T->rchild = NULL;
T->data = x;
}
else if(x < T->data)
T->lchild = Insert_elem(T->lchild, x);
else if(x > T->data)
T->rchild = Insert_elem(T->rchild, x);
return T;
}
Bitree
detele_elem(Bitree T, int x)
{
Bitree tmp;
if(T->data > x)
T->lchild = detele_elem(T->lchild, x);
else if(T->data < x)
T->rchild = detele_elem(T->rchild, x);
else
if(T->lchild != NULL && T->rchild != NULL) {
tmp = Find_min(T->rchild);
T->data = tmp->data;
detele_elem(T->rchild, T->data);
//有两个儿子那么把右子树最小元素替代此节点 再删除最小的那个元素
} else {
tmp = T;
if(T->lchild == NULL)
T = T->rchild;
else if(T->lchild == NULL)
T = T->lchild;
}//有一个或者零个元素
return T;
}
Bitree
build_tree(Bitree T, int n)
{
int i, x;
for (i = 0; i < n; i++) {
scanf("%d", &x);
printf("%d\n", x);
T = Insert_elem(T, x);
}
return T;
}
int main(int argc, char const *argv[]) {
#ifndef _OJ_ //ONLINE JUDGE
freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
Bitree T = NULL, T1 = NULL;
int n;
scanf("%d", &n);
T = build_tree(T, n);
printf("T == %p\n", T);
T1 = Find_x(T, 3);
printf("%d\n", T1->data);
T1 = Find_min(T);
printf("min == %d\n", T1->data);
T1 = Find_max(T);
printf("max == %d\n", T1->data);
detele_elem(T, 5);
T1 = Find_max(T);
printf("max1 == %d\n", T1->data);
return 0;
}