二叉排序树(AVL树)源码

二叉排序树(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);
        }
    }

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值