zoukankan      html  css  js  c++  java
  • 数据结构(复习)--------关于二叉查找树

    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;
    }
    
  • 相关阅读:
    【NOIP2016提高A组模拟8.19】(雅礼联考day2)公约数
    【NOIP2016提高A组模拟8.19】(雅礼联考day2)树上路径
    【NOIP2012模拟10.31】掷骰子
    【NOIP2016提高A组模拟8.17】(雅礼联考day1)总结
    【初中部 NOIP提高组 二试】模拟赛B总结
    【NOIP2012模拟11.1】塔(加强)
    【NOIP2016提高A组模拟8.17】(雅礼联考day1)Binary
    【NOIP2016提高A组模拟8.17】(雅礼联考day1)Value
    【NOIP2016提高A组模拟8.17】(雅礼联考day1)Matrix
    【NOIP2016提高A组模拟8.15】Garden
  • 原文地址:https://www.cnblogs.com/airfand/p/5080302.html
Copyright © 2011-2022 走看看