C++ 自平衡二叉搜索树的实现
头文件
// AVLTree.h for class avltree
#ifndef AVLTREE_H__________
#define AVLTREE_H__________
//#include <AFX.H>
typedef int BOOL;
#define NULL 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
struct TreeNode // AVL树数据结构
{
ElemType data;
int color;
struct TreeNode *parent;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(ElemType val);
int GetLeftHight();
int GetRightHight();
int GetDiffHight();
void GetNodes(TreeNode *pNode, int h);
};
// 栈类 用于存放查找结点的路径,便于回溯找到最小不平衡结点
class CStack
{
public:
CStack(int nMaxSize = 100);
~CStack();
BOOL Pop(TreeNode *& node);
BOOL Push(TreeNode * node);
BOOL Top(TreeNode *&node);
BOOL GetNext(TreeNode* &node);
int Size()const{return m_nCount; }
private:
int m_nCount;
int m_nCurPos;
int m_nMaxSize;
TreeNode* *m_arrNode; // 存放数据结点
};
// AVL树类 自平衡二叉搜索树
class CAVLTree
{
public:
CAVLTree();
~CAVLTree();
int Insert(ElemType val);
int Remove(ElemType val);
TreeNode* Find(const ElemType &val);
void DoBalance(TreeNode *& pCurNode, TreeNode *& pParent, int nLRFlag);
void PrintTree();
void EmptyTree();
int GetSize()const { return m_nSize; }
private:
void GetNoBalanceNode(CStack &st, TreeNode *& pCurNode, TreeNode *& pParent, int &nLRFlag);
BOOL LL_Rotate(TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag);
BOOL LR_Rotate(TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag);
BOOL RR_Rotate(TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag);
BOOL RL_Rotate(TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag);
void PrintTree(TreeNode *& pNode);
void GetNodes(CStack &st, TreeNode *pNode);
void SwapNodes(TreeNode *&pNode1, TreeNode *&pNode2);
private:
TreeNode *m_root;
int m_nSize;
};
#endif
实现文件
// AVLTree.cpp for implete class CAVLTree
#include <iostream>
#include "AVLTree.h"
#include <Windows.h>
using namespace std;
///////////////////////
/// constructure functions
//////////////////////////////////////////////// struct TreeNode implete
//////////////
TreeNode::TreeNode( ElemType val ) // 构造函数
{
data = val;
left = NULL;
right = NULL;
parent = NULL;
color = 0;
}
int nHight = 0;
int TreeNode::GetLeftHight()
{ // 获取结点左子树高度
nHight = 0;
GetNodes(this->left, 0);
return nHight;
}
int TreeNode::GetRightHight()
{ // 获取结点右子树高度
nHight = 0;
GetNodes(this->right, 0);
return nHight;
}
int TreeNode::GetDiffHight()
{ // 获取结点左右子树高度的差,当放回值的绝对值大于1时,该结点为不平衡结点,需要进行结点的自平衡处理
return (GetLeftHight() - GetRightHight());
}
void TreeNode::GetNodes(TreeNode *pNode, int h)
{ // 递归直到搜索到叶子结点,取最大的值为某结点到叶子结点的高度
if (pNode == NULL)
{
nHight = (nHight > h)? nHight:h;
return;
}
h++;
GetNodes(pNode->left, h);
GetNodes(pNode->right, h);
}
///////////////////////////////////////////////////////// class CStack implete
/////////////////
CStack::CStack( int nMaxSize ) // 构造函数
{
m_nCount = 0;
m_nMaxSize = nMaxSize;
m_arrNode = new TreeNode *[m_nMaxSize];
}
CStack::~CStack() // 析构函数
{
delete []m_arrNode;
}
BOOL CStack::Pop( TreeNode *& node ) // 出栈
{
if (m_nCount <= 0)
return FALSE;
m_nCount--;
node = m_arrNode[m_nCount];
return TRUE;
}
BOOL CStack::Push( TreeNode * node ) // 进栈
{
if(m_nCount < m_nMaxSize-1)
{
m_arrNode[m_nCount] = node;
m_nCount++;
return TRUE;
}
return FALSE;
}
BOOL CStack::Top( TreeNode *&node ) // 获取栈顶值
{
if (m_nCount > 0)
{
node = m_arrNode[m_nCount-1];
m_nCurPos = m_nCount - 1;
return TRUE;
}
return FALSE;
}
BOOL CStack::GetNext( TreeNode* &node ) // 第一次返回的值为栈顶的下一数值
{
if (m_nCurPos-1 < m_nCount-1 && m_nCurPos-1 >= 0)
{
m_nCurPos--;
node = m_arrNode[m_nCurPos];
return TRUE;
}
return FALSE;
}
///////////////////////////////////////////////////////// class CAVLTree implete
//////////////////////
CAVLTree::CAVLTree() // 构造函数
{
m_root = NULL;
m_nSize = 0;
}
CAVLTree::~CAVLTree()
{
EmptyTree(); //释放该树结构所有结点
}
int CAVLTree::Insert( ElemType val ) // 插入树结点
{
CStack stNodes(100000);
TreeNode *pNewNode = new TreeNode(val);
TreeNode *pNode = m_root;
TreeNode *preNode = NULL;
int nFlag; // 0--left 1--right
if (m_root == NULL)
{ // 该树为空
m_root = pNewNode;
cout<< "Insert root node: " << pNewNode->data <<" succeed." <<endl;
// Sleep(500);
m_nSize++;
return 1;
}
while(1)
{ // 查找要插入的位置
preNode = pNode;
if (val < pNode->data)
{
stNodes.Push(pNode);
pNode = pNode->left;
nFlag = 0;
}
else if (val > pNode->data)
{
stNodes.Push(pNode);
pNode = pNode->right;
nFlag = 1;
}
else
{
delete pNewNode;
return 0;
}
if (!pNode) //页子结点
{
if (nFlag == 0)
{
preNode->left = pNewNode;
}
else
preNode->right = pNewNode;
// Sleep(500);
break;
}
}
TreeNode *pNBLNode = NULL;
TreeNode *pNBLParent = NULL;
nFlag = 0;
GetNoBalanceNode(stNodes, pNBLNode, pNBLParent, nFlag);
if (pNBLNode)
{
DoBalance(pNBLNode, pNBLParent, nFlag);
}
m_nSize++;
cout<< "Insert "<< m_nSize <<" node: " << pNewNode->data <<" succeed." <<endl;
return 1;
}
int CAVLTree::Remove( ElemType val ) // 删除某一结点
{
if (!m_root) return 0;
CStack stNodes(100000); // 记录查找的路径结点
TreeNode *pNode = m_root;
TreeNode *pPreNode = m_root;
int nLRFlag;
while(pNode)
{
if (val < pNode->data)
{
stNodes.Push(pNode);
if (pNode->left)
{
pPreNode = pNode;
}
pNode = pNode->left;
nLRFlag = 0;
}
else if (val > pNode->data)
{
stNodes.Push(pNode);
if (pNode->right)
{
pPreNode = pNode;
}
pNode = pNode->right;
nLRFlag = 1;
}
else break;
}
if (!pNode) //没找到要删除的结点
return 0;
if (!stNodes.Top(pPreNode))
{ // tree has only one root node.
pPreNode = NULL;
if (pNode->left == NULL && pNode->right == NULL)
{
delete pNode;
m_root = NULL;
m_nSize--;
return 1;
}
}
if (pNode->left) //pNode为要删除的结点
{ // 寻找该结点的左子树中最大的结点与之交换位置
TreeNode *pNodeDel = pNode->left;
TreeNode *pPre = pNode;
stNodes.Push(pPre);
while(pNodeDel->right)
{
pPre = pNodeDel;
stNodes.Push(pPre);
pNodeDel = pNodeDel->right;
}
SwapNodes(pNode, pNodeDel); // 将要删除的结点与符合要求的叶子结点交换,然后删除该叶子结点
if (pPre->left == pNodeDel)// pNode 左边只有一个叶子结点
{
pPre->left = pNodeDel->left;
}
else
pPre->right = pNodeDel->left;
delete pNodeDel; // 释放叶子结点
}
else if (pNode->right)
{ // 寻找该结点的右子树中最小的结点与之交换位置
TreeNode *pNodeDel = pNode->right;
TreeNode *pPre = pNode;
stNodes.Push(pPre);
while(pNodeDel->left)
{
pPre = pNodeDel;
stNodes.Push(pPre);
pNodeDel = pNodeDel->left;
}
SwapNodes(pNode, pNodeDel);
pPre->right = pNodeDel->left;
delete pNodeDel;
}
else // 该结点为叶子结点
{
delete pNode;
if (nLRFlag == 0)
{
pPreNode->left = NULL;
}
else
pPreNode->right = NULL;
}
cout << "Remove node: " << val << " succeeded!\n";
// Sleep(500);
/// 检查不平衡结点
TreeNode *pNBLNode = NULL;
TreeNode *pPreNBLNode = NULL;
nLRFlag = 0;
GetNoBalanceNode(stNodes, pNBLNode, pPreNBLNode, nLRFlag);
if (pNBLNode)
{
DoBalance(pNBLNode, pPreNBLNode, nLRFlag);
}
m_nSize--;
return 1;
}
TreeNode* CAVLTree::Find( const ElemType &val ) // 查找某一结点
{
if (m_root == NULL) return NULL;
TreeNode *pNode = m_root;
while (pNode)
{
if (pNode->data < val)
{
pNode = pNode->right;
}
else if (pNode->data > val)
{
pNode = pNode->left;
}
else
{
cout << "Find node: " << val << " succeeded!\n";
return pNode;
}
}
return NULL;
}
// 获取不平衡的结点的信息
void CAVLTree::GetNoBalanceNode( CStack &st, TreeNode *& pCurNode, TreeNode *& pParent, int &nLRFlag )
{
TreeNode *pNode;
if (!st.Top(pNode)) return ;
while(1)
{
int nDiff = pNode->GetDiffHight();
if (nDiff > 1 || nDiff < -1)
{
pCurNode = pNode;
if (st.GetNext(pParent))
{
if (pParent->left == pCurNode)
{
nLRFlag = 0; // left child
}
else /*if (pParent->right == pCurNode)*/
{
nLRFlag = 1; // right child
}
return ;
}
}
if (!st.GetNext(pNode))
{
return ;
}
}
}
// 自平衡处理函数
void CAVLTree::DoBalance( TreeNode *& pCurNode, TreeNode *& pParent, int nLRFlag )
{
cout << "Call DoBalance() succeeded!\n";
if (pCurNode->GetLeftHight() > pCurNode->GetRightHight())
{
if (pCurNode->left->GetLeftHight() > pCurNode->left->GetRightHight())
{
LL_Rotate(pCurNode, pParent, nLRFlag); // LR型 平衡处理
}
else
LR_Rotate(pCurNode, pParent, nLRFlag); // LL型 平衡处理
}
else
{
if (pCurNode->right->GetLeftHight() > pCurNode->right->GetRightHight())
{
RL_Rotate(pCurNode, pParent, nLRFlag); // RL型 平衡处理
}
else
RR_Rotate(pCurNode, pParent, nLRFlag); // RR型 平衡处理
}
}
BOOL CAVLTree::LL_Rotate( TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag )
{
cout << "Call LL_Rotate() succeeded!\n";
TreeNode *pTempRoot = pCurNode->left;
TreeNode *pTempRootR = pTempRoot->right;
pTempRoot->right = pCurNode;
pCurNode->left = pTempRootR;
if (pParentNode)
{
if (nLRFlag == 0)
{
pParentNode->left = pTempRoot;
}
else
pParentNode->right = pTempRoot;
}
else // root
m_root = pTempRoot;
return TRUE;
}
BOOL CAVLTree::LR_Rotate( TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag )
{
cout << "Call LR_Rotate() run succeeded!\n";
TreeNode *pNodeA = pCurNode->left;
TreeNode *pNodeB = pNodeA->right;
TreeNode *pPreB = pNodeA;
TreeNode *pTempRoot = NULL;
while(pNodeB->right)
{
pPreB = pNodeB;
pNodeB = pNodeB->right;
}
pTempRoot = pNodeB;
if (pTempRoot == NULL) // pNodeA 的右子树为空
{
pTempRoot = pNodeA;
pTempRoot->right = pCurNode;
pCurNode->left = NULL;
}
else
{
pPreB->right = pTempRoot->left;
pTempRoot->left = pNodeA;
pTempRoot->right = pCurNode;
pCurNode->left = NULL;
}
if (pParentNode)
{
if (nLRFlag == 0)
{
pParentNode->left = pTempRoot;
}
else
pParentNode->right = pTempRoot;
}
else // root
m_root = pTempRoot;
return TRUE;
}
BOOL CAVLTree::RR_Rotate( TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag )
{
cout << "Call RR_Rotate() succeeded!\n";
TreeNode *pTempRoot = pCurNode->right;
TreeNode *pTempRootL = pTempRoot->left;
pTempRoot->left = pCurNode;
pCurNode->right = pTempRootL;
if (pParentNode)
{
if (nLRFlag == 0)
{
pParentNode->left = pTempRoot;
}
else
pParentNode->right = pTempRoot;
}
else // root
m_root = pTempRoot;
return TRUE;
}
BOOL CAVLTree::RL_Rotate( TreeNode *& pCurNode, TreeNode *& pParentNode, const int &nLRFlag )
{
cout << "Call RL_Rotate() run succeeded!\n";
TreeNode *pNodeA = pCurNode->right;
TreeNode *pNodeB = pNodeA->left;
TreeNode *pPreB = pNodeA;
while(pNodeB->left)
{
pPreB = pNodeB;
pNodeB = pPreB->left;
}
TreeNode *pTempRoot = pNodeB;
if (pTempRoot == NULL)
{
pTempRoot = pNodeA;
pCurNode->right = NULL;
pTempRoot->left = pCurNode;
}
else
{
pTempRoot->left = pCurNode;
pCurNode->right = NULL;
pPreB->left = pTempRoot->right;
pTempRoot->right = pNodeA;
}
if (pParentNode)
{
if (nLRFlag == 0)
{
pParentNode->left = pTempRoot;
}
else
pParentNode->right = pTempRoot;
}
else // root
m_root = pTempRoot;
return TRUE;
}
void CAVLTree::PrintTree() // 打印树结点
{
if (!m_root)
{
cout << "The tree is empty!\n";
return ;
}
PrintTree(m_root); // 调用递归遍历结点函数
cout << endl;
}
void CAVLTree::PrintTree( TreeNode *& pNode )
{
if (pNode)
{
cout << pNode->data << " ";
PrintTree(pNode->left);
PrintTree(pNode->right);
}
}
void CAVLTree::EmptyTree() // 清空结点,释放结点空间
{
if (!m_root)
{
return;
}
CStack stNodes(10000);
GetNodes(stNodes, m_root);
TreeNode *pTemp;
if (stNodes.Pop(pTemp))
{
delete pTemp;
}
m_root = NULL;
cout << "Emptied the tree succeeded!\n";
}
void CAVLTree::GetNodes( CStack &st, TreeNode *pNode )
{
if (pNode)
{
GetNodes(st, pNode->left);
GetNodes(st, pNode->right);
}
}
void CAVLTree::SwapNodes( TreeNode *&pNode1, TreeNode *&pNode2 ) // 交换两个结点
{
ElemType val = pNode1->data;
pNode1->data = pNode2->data;
pNode2->data = val;
}
测试文件
/// test.cpp for test the class CAVLTree
#include <iostream>
#include "AVLTree.h"
#include <ctime>
using namespace std;
void LL_Test();
void RR_Test();
void LR_Test();
void RL_Test();
void time_Test();
void main()
{
time_Test();
// LL_Test();
// RR_Test();
// LR_Test();
// RL_Test();
return;
}
void time_Test()
{
cout << "////////////////time_Test Function.\n";
CAVLTree tree;
clock_t t_insert, t_print, t_find; // 分别记录插入数据时间和打印数据时间
int nArrNodes[30000];
srand((unsigned)time(NULL));
// srand(0);
t_insert = clock();
for (int i = 0; i < 30000; i++)
{
nArrNodes[i] = rand();
while (1)
{
if (tree.Find(nArrNodes[i]) == NULL)
{
tree.Insert(nArrNodes[i]);
break;
}
else
nArrNodes[i] = rand();
}
}
t_insert = clock() - t_insert;
t_print = clock();
tree.PrintTree();
t_print = clock() - t_print;
t_find = clock();
tree.Find(32725);
t_find = clock() - t_find;
cout << "The tree nodes count is: " << tree.GetSize() << endl;
cout << "Insert data need time: " << t_insert << "ms." << endl;
cout << "Print data need time: " << t_print << "ms." << endl;
cout << "Find one data need time: " << t_find << "ms." << endl;
}
void LL_Test()
{
cout << "/////////////////LL_Test" << endl;
CAVLTree tree;
tree.Insert(9);
tree.Insert(5);
tree.Insert(11);
tree.Insert(6);
tree.Insert(15);
tree.Insert(4);
tree.Insert(3);
tree.PrintTree();
tree.Remove(9);
tree.PrintTree();
cout << endl;
return;
}
void RR_Test()
{
cout << "//////////////////RR_Test" << endl;
CAVLTree tree;
tree.Insert(4);
tree.Insert(2);
tree.Insert(6);
tree.Insert(5);
tree.Insert(9);
tree.Insert(11);
tree.PrintTree();
cout << endl;
return;
}
void LR_Test()
{
cout << "////////////////LR_Test" << endl;
CAVLTree tree;
tree.Insert(9);
tree.Insert(4);
tree.Insert(11);
tree.Insert(2);
tree.Insert(6);
tree.Insert(5);
tree.PrintTree();
tree.Remove(6);
tree.PrintTree();
cout << endl;
return;
}
void RL_Test()
{
cout << "//////////////////RL_Test" << endl;
CAVLTree tree;
tree.Insert(4);
tree.Insert(2);
tree.Insert(9);
tree.Insert(6);
tree.Insert(11);
tree.Insert(5);
tree.PrintTree();
tree.Insert(7);
tree.Insert(8);
tree.PrintTree();
tree.Remove(6);
tree.PrintTree();
tree.Remove(11);
tree.PrintTree();
tree.Remove(7);
tree.PrintTree();
tree.Remove(8);
tree.PrintTree();
tree.Remove(9);
tree.PrintTree();
tree.Remove(4);
tree.PrintTree();
tree.Remove(2);
tree.PrintTree();
tree.Remove(5);
tree.PrintTree();
cout << endl;
return;
}