# 二叉排序树（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 remove(AVLNode* &tree, AVLNode* node);
public:
AVLTree();
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();
}

}

{
if(tree == NULL) //tree用的是引用，这里会改tree的值
{
node->treeHeight = 1;
tree = node;
return;
}
if(node->nodeValue < tree->nodeValue)
{
//为了理解简单，统一调用reblance,否则就用reblance的第一个分支里的代码
}
else
{
//为了理解简单，统一调用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::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++)
{
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树）源码 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)