二叉排序树(AVL树)源码

原创 2016年12月23日 14:11:16

二叉排序树(AVL树)源码


AVLTree.h源码

#pragma once
#include "stdafx.h"
#include <vector>
using namespace std;
class AVLNode
{
public:
    float nodeValue;
    int treeHeight;
    AVLNode* lChild;
    AVLNode* rChild;
    AVLNode(float v){lChild = NULL; rChild = NULL; nodeValue = 0; treeHeight = 0; nodeValue = v;}
    int getLeftHeight(){return lChild != NULL?lChild->treeHeight:0;}
    int getRightHeight(){return rChild != NULL?rChild->treeHeight:0;}
    void refreshHeight()
    {
        int leftHeight = getLeftHeight();
        int rightHeight = getRightHeight();
        treeHeight = (leftHeight>rightHeight?leftHeight:rightHeight)+1;
    }
};
class AVLTree
{
private:
    AVLNode* root;
    void lRotation(AVLNode* &tree); //左旋,解决RR
    void lrRotation(AVLNode* &tree); //先左旋,再右旋,解决LR
    void rRotation(AVLNode* &tree); //右旋,解决LL
    void rlRotation(AVLNode* &tree); //先右旋,再左旋,解决RL
    void rebalance(AVLNode* &tree); //删除节点后,需要再平衡
    void add(AVLNode* &tree, AVLNode* node);
    void remove(AVLNode* &tree, AVLNode* node);
public:
    AVLTree();
    void add(AVLNode* node);
    void remove(AVLNode* node);
    vector<AVLNode*> getSortedList();
};

AVLTree.cpp源码

#include "stdafx.h"
#include "AVLTree.h"
AVLTree::AVLTree()
{
    root = NULL;
}


void AVLTree::lRotation(AVLNode* &tree) //右右,需要左旋
{
    //将右子树下的左子树作为原本根节点的右子树,将右子树的根节点作为新树的根节点,将原先的根节点作为新树的左子树
    AVLNode* newTree = tree->rChild;
    tree->rChild = newTree->lChild;
    newTree->lChild = tree;
    tree = newTree;
    tree->lChild->refreshHeight();
    tree->refreshHeight();
}

void AVLTree::rlRotation(AVLNode* &tree) //右左,需要先右旋(变成右右),再左旋
{
    rRotation(tree->rChild);
    lRotation(tree); //这个左旋,是不是可以看右旋的情况,再考虑要不要左旋?

}

void AVLTree::rRotation(AVLNode* &tree) //左左,需要右旋
{
    //将做子树下的右子树作为原本根节点的左子树,将左子树的根节点作为新树的根节点,将原先的根节点作为新树的右子树
    AVLNode* newTree = tree->lChild;
    tree->lChild = newTree->rChild;
    newTree->rChild = tree;
    tree = newTree;
    tree->rChild->refreshHeight();
    tree->refreshHeight();
}
void AVLTree::lrRotation(AVLNode* &tree) //左右,需要先左旋(变成左左),再右旋
{

    lRotation(tree->lChild); 
    rRotation(tree);//这个右旋,是不是可以看左旋的情况,再考虑要不要右旋?

}
void AVLTree::rebalance(AVLNode* &tree)
{
    if(tree->getLeftHeight() - tree->getRightHeight() >=2)
    {
        int llHeight = tree->lChild != NULL?tree->lChild->getLeftHeight():0;
        int lrHeight = tree->lChild != NULL?tree->lChild->getRightHeight():0;
        if(llHeight >= lrHeight)
            rRotation(tree);
        else
            lrRotation(tree);
    }
    else if(tree->getRightHeight()-tree->getLeftHeight()>=2)
    {
        int rlHeight = tree->rChild != NULL?tree->rChild->getLeftHeight():0;
        int rrHeight = tree->rChild != NULL?tree->rChild->getRightHeight():0;
        if(rrHeight >=rlHeight)
            lRotation(tree);
        else
            rlRotation(tree);

        tree->refreshHeight();
    }

}

void AVLTree::add(AVLNode* &tree, AVLNode* node)
{
    if(tree == NULL) //tree用的是引用,这里会改tree的值
    {
        node->treeHeight = 1;
        tree = node;
        return;
    }
    if(node->nodeValue < tree->nodeValue)
    {
        add(tree->lChild, node);
        //为了理解简单,统一调用reblance,否则就用reblance的第一个分支里的代码
    }
    else
    {
        add(tree->rChild, node);
        //为了理解简单,统一调用reblance,否则就用reblance的第二个分支里的代码

    }
    tree->refreshHeight();
    rebalance(tree);
}
void AVLTree::remove(AVLNode* &tree, AVLNode* node)
{
    if(tree == NULL)
    {
        return;
    }
    if(tree == node)
    {
        if(tree->lChild != NULL && tree->rChild != NULL)
        {
            //从左子树里找到最大的节点,替补tree
            AVLNode* temp = tree->lChild;
            while (temp->rChild != NULL)
            {
                temp = temp->rChild;
            }
            remove(tree->lChild,temp); //需要刷新树的height
            temp->lChild = tree->lChild;
            temp->rChild = tree->rChild;
            tree = temp;
        }
        else 
        {
            tree = tree->lChild!=NULL?tree->lChild:tree->rChild; //直接将非空子树根作为新的根
            if(tree == NULL) return;
        }
    }
    else
    {
        if(node->nodeValue <= tree->nodeValue&& tree->lChild != NULL )
        {
            remove(tree->lChild, node);
        }
        if(node->nodeValue >= tree->nodeValue && tree->rChild != NULL )
        {
            remove(tree->rChild, node);
        }
    }
    tree->refreshHeight();
    rebalance(tree);
}

void AVLTree::add(AVLNode* node)
{
    add(root, node);
}

void AVLTree::remove(AVLNode* node)
{
    remove(root, node);
}
vector<AVLNode*> AVLTree::getSortedList() //中序遍历,获得排序好的结果(挑战了下,采用非递归写法)
{

    vector<AVLNode*> nodeList;
    if(root != NULL)
    {
        vector<AVLNode*> stack;
        vector<int> flagStack;
        stack.push_back(root);
        flagStack.push_back(0);
        while(stack.size() > 0)
        {
            AVLNode* cNode = stack[stack.size()-1];
            int flag = flagStack[flagStack.size()-1];
            if(flag == 0)
            {
                flagStack[stack.size()-1]++;


                if(cNode->lChild != NULL)
                {
                    stack.push_back(cNode->lChild); //访问左子树
                    flagStack.push_back(0);
                }
            }
            else if(flag == 1)
            {
                flagStack[flagStack.size()-1]++;

                //左子树访问完毕
                nodeList.push_back(cNode);


                if(cNode->rChild != NULL)
                {
                    stack.push_back(cNode->rChild);
                    flagStack.push_back(0);
                }
            }
            else
            {
                stack.pop_back();
                flagStack.pop_back();
            }

        }
    }
    return nodeList;
}

AVLTreeTest.h源码

#include "stdafx.h"
#include "AVLTree.h"
#include <iostream>
#include <vector>
using namespace std;
class AVLTreeTest
{
public:
    void Print(AVLTree* tree)
    {
        vector<AVLNode*> sortedList = tree->getSortedList();
        for(int i=0; i<sortedList.size(); i++)
        {
            cout << sortedList[i]->nodeValue << " ";
        }
        cout <<endl;
    }
    void DoTest()
    {
        AVLTree* tree = new AVLTree();
        vector<AVLNode*> nodeList;

        nodeList.push_back(new AVLNode(43));
        nodeList.push_back(new AVLNode(14));
        nodeList.push_back(new AVLNode(32));
        nodeList.push_back(new AVLNode(52));
        nodeList.push_back(new AVLNode(126));
        nodeList.push_back(new AVLNode(93));
        nodeList.push_back(new AVLNode(131));
        nodeList.push_back(new AVLNode(44));
        nodeList.push_back(new AVLNode(123));
        nodeList.push_back(new AVLNode(9));


        for(int i=0;i<nodeList.size();i++)
        {
            tree->add(nodeList[i]);
            Print(tree);
        }
        for(int i=nodeList.size()-1; i>=0;i--)
        {
            int r = i*rand()/RAND_MAX;
            tree->remove(nodeList[r]);
            nodeList.erase(nodeList.begin()+r);
            Print(tree);
        }
    }

};
版权声明:本文为博主原创文章,未经博主允许不得转载。

看图说话之平衡二叉排序树(AVL树)

介绍了平衡二叉排序树的基本原理,重点介绍了AVL树的基本实现方法,并且给出了完整java代码实现...

二叉排序树、红黑树、AVL树最简单的理解

前言[为什么写这篇]之前在知乎上看过一个提问:为什么红黑树比AVL树用的场景更为广泛,红黑树在 STL 和 Linux 都有一定的运用。而AVL树也在 Windows进程地址空间管理 中得到了使用。既...

二叉排序树(B树)和平衡树(AVL树)

     二叉排序树,也称B树,是查找算法中比较常提到的一种数据结构,本文介绍其基本概念和查找过程,并分析其查找效率,进而引出了平衡树(AVL树)的概念。 B树的结构   B树即为...

二叉树-详解平衡二叉排序树AVL

平衡二叉搜索树AVL也许因为输入值不够随机,也许因为输入顺序的原因,还或许一些插入、删除操作,会使得二叉搜索树失去平衡,造成搜索效率低落的情况。 比如上面两个树,在平衡树上寻找15就只要...

BST二叉排序树,AVL平衡二叉树,RBT红黑树,B-树,B+树,B*树

BST二叉搜索树,AVL平衡二叉树,RBT红黑树,B-树,B+树,B*树

二叉排序树C实现(含完整源码)

二叉排序树简介      二叉排序树(Binary Sort Tree,简称BST),又称二叉查找树,是红黑树、AVL树等的基础。它或是一棵空树,或者是具有下列性质的一棵二叉树: ...

完整详尽的二叉排序树性质及源码和注释 C语言 可直接运行

/** *二叉查找树的性质: * 1)若其左子树不空,左子树上所有节点的值均小于它的根节点的值 * 2)若其右子树不空,右子树上所有节点的值均大于它的根节点的值 * 3)它的左右子树也分别为二叉排序树...

【数据结构与算法】二叉排序树C实现(含完整源码)

二叉排序树(Binary Sort Tree,简称BST),又称二叉查找树,是红黑树、AVL树等的基础。它或是一棵空树,或者是具有下列性质的一棵二叉树: 1、若它的左子树不空,则左子树上所有节点...

STL源码笔记(17)—二叉排序树BST(C++封装)

STL 二叉排序树的C++实现
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:二叉排序树(AVL树)源码
举报原因:
原因补充:

(最多只允许输入30个字)