数据结构(复习)--------关于二叉查找树

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("没有找到!
");          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
", 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
", 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
", T);

    T1 = Find_x(T, 3);

    printf("%d
", T1->data);

    T1 = Find_min(T);

    printf("min == %d
", T1->data);

    T1 = Find_max(T);

    printf("max == %d
", T1->data);

    detele_elem(T, 5);

    T1 = Find_max(T);

    printf("max1 == %d
", T1->data);

    return 0;
}
原文地址:https://www.cnblogs.com/airfand/p/5080302.html