二叉搜索树与平衡二叉树

 二叉搜索树(BST)
二叉搜索树也是一种树,适用与一般二叉树的全部操作,但二叉搜索树能够实现数据的快速查找
性质:
非空左子树的所有键值小于其根节点的键值
非空右子树的所有键值大于其根节点的键值
左右子树都是二叉搜索树

二叉搜索树的插入、查找、删除
删除主要分三种情况来讨论:
(1)要删除的是叶子结点:直接删除
(2)要删除的节点只有一个孩子节点:将其父节点的指针指向要删除节点的孩子节点
(3)要删除的节点有左、右两颗子树:
用另一个结点替代被删除结点:右子树的最小元素或者左子树的最大元素
其中删除操作的代码较复杂,暂未给出。

平衡二叉树(AVL树)(此处的AVL起源于一个发现者的人名)
以上已经知道一个数组二分查找的算法,可以以二叉查找树来实现,但一般该二叉查找树的效率比不上/数组的二分查找
这是由于二叉查找树是不平衡的。。要想缩短一个二叉搜索树的查找时间,需要将二叉查找树调整为平衡二叉树。

衡量二叉搜索树搜索效率的标准:平均查找长度(ASL):每个结点比较次数和/结点数

平衡因子(BF):左子树的高度减去右子树的高度。
判断一个二叉搜索树是否为一个平衡二叉树:|BF|小于等于1

当对一个平衡二叉树插入一个结点后,AVL树就变的不平衡了
平衡二叉树的调整:分为四种情况
(1)多余点在树的不平衡子树的根结点的右子树的右边:RR插入,需要RR旋转
(2)多余点在树的不平衡子树的根结点的左子树的左边:LL插入,需要LL旋转
(3)多余点在树的不平衡子树的根结点的右子树的左边:RL插入,需要RL旋转
(3)多余点在树的不平衡子树的根结点的左子树的右边:LR插入,需要LR旋转

平衡二叉树的代码后续会给出

以下代码实现了二叉树 的插入、查找操作。。并给出了一个《剑指offer》上的一道笔试题:查找一个二叉搜索树中第k小的元素。

#include <iostream>
#include <stack>
using namespace std;
typedef int ElementType;
typedef struct TreeNode{
    ElementType val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(ElementType x) : val(x),left(NULL),right(NULL){}
}Node, *BST;
int count=1;    
/*插入的方式建立一个二叉搜索树*/
BST Insert(ElementType x,BST bst)
{
    if(bst==NULL){
        bst = new Node(x);
        bst->left = NULL;
        bst->right = NULL;
    }
    else{
        if(x<bst->val)
            bst->left = Insert(x,bst->left);
        else
            bst->right = Insert(x,bst->right);
    }
    return bst;
}
/*查找二叉搜索树中的某个元素,并返回该结点*/
BST Find(BST bst, ElementType num)
{
    if(!bst)
        return NULL;
    if(num < bst->val)
        return Find(bst->left,num);
    else if(num > bst->val)
        return Find(bst->right,num);
    else
        return bst;
    //return bst;
}
/*查找第k小的元素!采用前序遍历递归方法,当遍历到第k小的数时返回该节点(非空),并让程序逐级返回----此处不易理解*/
BST KthNode(BST bst, int k)
{    
    if(bst==NULL)
        return NULL;
    BST left = KthNode(bst->left,k);
    if(left!=NULL)
        return left;
    if(count==k)
        return bst;
    count++;
    BST right = KthNode(bst->right,k);
    if(right!=NULL)
        return right;
            
    return NULL;
}
//中序遍历
void inorderTraverse(BST bst)
{
    if(bst)
    {
        cout << bst->val << " ";
        inorderTraverse(bst->left);
        inorderTraverse(bst->right);
    }
}
//前序遍历---只有二叉搜索树的中序遍历输出的结果从小到大排列,后序遍历并不是从大到小排列
void preorderTraverse(BST bst)
{
    if(bst)
    {
        preorderTraverse(bst->left);
        cout << bst->val << " ";
        preorderTraverse(bst->right);
    }
}

int main()
{

    BST bst = NULL;
    bst = Insert(5,bst);
    bst = Insert(3,bst);
    bst = Insert(6,bst);
    bst = Insert(2,bst);
    bst = Insert(4,bst);
    bst = Insert(7,bst);
    
    inorderTraverse(bst);
    cout << endl;
    preorderTraverse(bst);
    cout << endl;
    Node* Knode = KthNode(bst, 5);
    cout << Knode->val << endl;
    Node* Fnode = Find(bst,4);
    cout << Fnode->val << endl;
}
    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/gouhailiang/article/details/53088778
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞