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