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

};
    原文作者:AVL树
    原文地址: https://blog.csdn.net/gamekit/article/details/53838718
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞