zoukankan      html  css  js  c++  java
  • 二叉排序树(BST)

    二叉排序树(BST)

    二叉排序树,又称二叉查找树(BST)

    左子树结点值<根节点值<右子树结点值

    如果用中序遍历来遍历一棵二叉排序树的话,可以得到一个递增的有序数列

    左根右

    二叉排序树的查找

    //二叉排序树结点
    typedef struct BSTNode{
        int key;
        struct BSTNode *lchild,*rchild;
    }BSTNode,*BSTree;
    

    查找是非常方便的,目标值和根节点比较,如果相等则成功,比根节点大往右去,比根节点小往左去。

    查找失败就返回null

    非递归方式:

    //在二叉排序树中查找值为key的结点
    BSTNode *BST_search(BSTree T, int key){
        while(T!=NULL&&key!=T->key){ 	//若树为空或等于根节点值,则结束循环
            if(key<T->key){				//小于,则在左子树
                T=T->lchild;
            }else{						//大于,则在右子树
                T=T->rchild;
            }       
        }
        return T;
    }
    

    最坏空间复杂度=O(1)

    递归方式:

    //在二叉排序树中查找值为key的结点(递归实现)
    BSTNode *BSTSearch(BSTree T,int key){
        if(T==NULL){
            return NULL;						//查找失败
        }
        if(key==T->key){
            return T;							//查找成功
        }else if(key <T->key){
            return BSTSearch(T->lchild,key);	//在左子树找
        }else{
             return BSTSearch(T->rchild,key);	//在右子树找
        }
    }
    

    最坏空间复杂度=O(h) 和树的高度相同

    二叉排序树的插入

    若原二叉排序树为空,则直接插入结点;

    否则,若关键字k小于根节点值,则插入到左子树,若关键字k大于根节点值,则插入到右子树。

    //在二叉排序树插入关键字为k的新节点(递归实现)
    int BST_Insert(BSTree &T,int k){
        if(T == NULL){				//原树为空,新插入的结点为根节点
            T=(BSTree)malloc(sizeof(BSTNode));
            T->key = k;
            T->lchild = T->rchild = NULL;
            return 1;				//返回1,插入成功
        }else if(k == T->key){		//树中不能存在相同关键字的结点,插入失败
            return 0;
        }else if(k<T->key){			//插入到T的左子树
            return BST_Insert(T->lchild,k);
        }else{						//插入到T的右子树
            return BST_Insert(T->rchild,k);
        }
    }
    

    最坏空间复杂度=O(h)

    二叉排序树的构造

    其实就是不断插入新节点的过程

    //按照str[]中的关键字序列建立二叉排序树
    void Creat_BST(BSTree &T,int str[],int n){
        T = NULL;				//初始化时T为空树
        int i = 0;
        while(i<n){				//依次将每个关键字插入到二叉排序树
            BST_Insert(T,str[i]);
            i++;
        }
    }
    

    不同的关键字序列可能得到同款二叉排序树,也可能得到不同款二叉排序树

    二叉排序树的删除

    先搜索找到目标结点:

    (需要保证二叉排序书的特性——左子树结点值<根节点值<右子树结点值)

    • 若是被删除的结点z是叶节点,则直接删除,不会破坏二叉排序树的性质。

    • 若结点z只有一棵左子树或右子树,则让z的子树称为z父节点的子树,替代z的位置

    • 若结点z有左、右两棵子树,则令z的直接后继(或直接前驱)替代z,然后从二叉排序树中删去这个直接后继(或直接前驱),这样就转换成了第一或第二种情况。

    进行中序遍历,可以得到一个递增的有序序列。

    用右子树最小的值来替代被删除的值(最左下)

    用左子树最大的值来替代被删除元素(最右下角)

    查找效率分析

    查找长度——在查找运算中,需要对比关键字的次数称为查找长度,反应了查找操作时间复杂度

    查找成功的平均查找长度ASL(Average Search Length)

    树高h,找到最下层的一个结点需要对比h次

    最坏情况:每个节点只有一个分支,树高h=结点数n。平均查找长度=O(n)

    最好情况:

    n个结点的二叉树最小高度为

    [lfloor log_2n floor+1 ]

    平均查找长度=

    [O(log_2n) ]

    查找失败

  • 相关阅读:
    ObjectiveC 语言入门教程 | MacCocoa
    Neopythonic memcached cliend
    python Preventing django from appending "_id" to a foreign key field Stack Overflow
    JQuery and python script | python | PyMantra
    Import error on django models.py
    如何成为Python高手 技术讨论 云计算开发者社区 Powered by Discuz!
    [Hadoop] 实际应用场景之 百度 Zhu_Julian's Notes (朱显杰的技术博客) 博客频道 CSDN.NET
    DjangoResources – Django
    hue
    Huseyin Yilmaz
  • 原文地址:https://www.cnblogs.com/jev-0987/p/13202233.html
Copyright © 2011-2022 走看看