此为头文件.h
#pragma once
class CAVLTree
{
public:
typedef struct _NODE
{
int nData;
_NODE* pLeft;
_NODE* pRight;
}NODE, *PNODE;
public:
CAVLTree();
virtual ~CAVLTree();
bool Insert(int nEle);// 插入数据
bool Erase(int nEle);// 删除数据
PNODE Find(int nFind);// 找数据
bool Change(int nFind, int nChange); // 更改数据
// 遍历
void PreOrder();// 前序
void MidOrder();// 中序
void LastOrder();// 后序
// 用于演示
void show();
void GetHeight();//获取总高度,左子树,右子数高度
protected:
// 内部接口
PNODE m_pRoot;//头指针
bool Insert(PNODE &pInsert, int nEle);
bool Erase(PNODE &pDelete, int nEle);// 删除数据
void Release(PNODE &pRelease); //释放空间
int GetHeight(PNODE &pHeight); //获取高度
bool GetMax(PNODE pMax, int &nMax);// 获取最大值
bool GetMin(PNODE pMin, int &nMin);// 获取最小值
void Balance(PNODE &pNode);// 处理不平衡情况
void SingleRight(PNODE &pK2);// 右旋
void SingleLeft(PNODE &pK2);// 左旋
void DoubleLR(PNODE &pK3);// 左右旋
void DoubleRL(PNODE &pK3);// 右左旋
PNODE Find(PNODE &pNode, int nFind);// 找数据
void PreOrder(const PNODE &pPreOrder);// 前序
void MidOrder(const PNODE &pPreOrder);// 中序
void LastOrder(const PNODE &pPreOrder);// 后序
// 用于演示
void PrintTree(PNODE& pNode, int nLayer);
};
此为源文件.cpp:
#include "stdafx.h"
#include "AVLTree.h"
#include <iostream>
using std::cout;
using std::endl;
CAVLTree::CAVLTree() :m_pRoot(nullptr)
{
}
CAVLTree::~CAVLTree()
{
Release(m_pRoot);
}
bool CAVLTree::Insert(int nEle)
{
return Insert(m_pRoot, nEle);
}
bool CAVLTree::Insert(PNODE &pInsert, int nEle)
{
bool bsuccess = true;
if (pInsert == nullptr) //到叶子节点插入
{
pInsert = new NODE;
pInsert->nData = nEle;
pInsert->pLeft = nullptr;
pInsert->pRight = nullptr;
return true;
}
if (nEle > pInsert->nData) //向右插入
{
bsuccess= Insert(pInsert->pRight, nEle);
}
if (nEle < pInsert->nData) //向左插入
{
bsuccess = Insert(pInsert->pLeft, nEle);
}
if (bsuccess)
{
Balance(pInsert);//平衡处理
}
return bsuccess;
}
bool CAVLTree::Erase(int nEle)
{
return Erase(m_pRoot, nEle);
}
bool CAVLTree::Erase(PNODE &pDelete, int nEle)
{
bool bSuccess = true;
if (pDelete == nullptr) //到叶子节点还未找到
{
return false;
}
if (nEle > pDelete->nData) //向右找
{
bSuccess = Erase(pDelete->pRight, nEle);
}
else if (nEle < pDelete->nData) //向左找,前面的else不能丢否则会丢失数据
{
bSuccess = Erase(pDelete->pLeft, nEle);
}
else //找到了
{
if (pDelete->pLeft == nullptr&&pDelete->pRight == nullptr)//叶子节点
{
delete[] pDelete;
pDelete = nullptr;
return true;
}
//先求左右子树高
int dwLeft = GetHeight(pDelete->pLeft);
int dwRight = GetHeight(pDelete->pRight);
//去较高的那一侧找替换点删除
if (dwLeft > dwRight)
{//去左子树找最大的值
int nMax = 0;
GetMax(pDelete->pLeft, nMax);//用最大的值替换
pDelete->nData = nMax;
bSuccess = Erase(pDelete->pLeft, nMax);//删除刚才最大的值
}
else
{//去右子树找最小的值
int nMin = 0;
GetMin(pDelete->pRight, nMin);//用最小的值替换
pDelete->nData = nMin;
bSuccess = Erase(pDelete->pRight, nMin);//删除刚才最小的值
}
}
if (bSuccess)
{
Balance(pDelete);
}
return bSuccess ;
}
//释放二叉树
void CAVLTree::Release(PNODE &pRelease)
{
if (pRelease)
{
Release(pRelease->pLeft);
Release(pRelease->pRight);
delete[] pRelease;
pRelease = nullptr;
}
}
void CAVLTree::GetHeight()
{
cout << "总数高:" << GetHeight(m_pRoot) << endl;
cout << "左子树高:" << GetHeight(m_pRoot->pLeft) << endl;
cout << "右子树高:" << GetHeight(m_pRoot->pRight) << endl << endl;
}
int CAVLTree::GetHeight(PNODE &pHeight)
{
if (pHeight == nullptr)
{
return 0;
}
int dwLeft = GetHeight(pHeight->pLeft);
int dwRight = GetHeight(pHeight->pRight);
return (dwLeft > dwRight ? dwLeft : dwRight) + 1;//返回子数高的那一个
}
bool CAVLTree::GetMax(PNODE pMax, int &nMax)
{
while (pMax->pRight)
{
pMax = pMax->pRight;
}
nMax = pMax->nData;
return true;
}
bool CAVLTree::GetMin(PNODE pMin, int &nMin)
{
while (pMin->pLeft)
{
pMin = pMin->pLeft;
}
nMin = pMin->nData;
return true;
}
//处理不平衡的状态
void CAVLTree::Balance(PNODE &pNode)
{
int nLHeight = GetHeight(pNode->pLeft);
int nRHeight = GetHeight(pNode->pRight);
if (nLHeight - nRHeight > 1)// 如果左边高
{
nLHeight = GetHeight(pNode->pLeft->pLeft);
nRHeight = GetHeight(pNode->pLeft->pRight);
if (nLHeight >= nRHeight)//下级的左比右高
{
SingleRight(pNode);//右旋
}
else
{
DoubleLR(pNode);//左右旋
}
}
else if (nLHeight - nRHeight <-1)
{
nLHeight = GetHeight(pNode->pRight->pLeft);
nRHeight = GetHeight(pNode->pRight->pRight);
if (nRHeight >= nLHeight)//下级的右比左高
{
SingleLeft(pNode);//左旋
}
else
{
DoubleRL(pNode);//右左旋
}
}
}
//左旋
void CAVLTree::SingleRight(PNODE &pK2)
{
//先保存K1节点的值
PNODE pK1 = pK2->pLeft;
//让X变成K2的左子树 等于 K1的右子树
pK2->pLeft = pK1->pRight;
//让K2变成K1的右子树
pK1->pRight = pK2;//pK2的实际地址没变,值也没变
//让k1成为新的根节点,因为m_pRoot->pLeft原来指向K2,现在指向为m_pRoot->pLeft指向了K1,K2
pK2 = pK1;//pK2的实际地址变了,但是原来指向的空间保存在K1指向的右子数里了,也就是指针交换了
}
//右旋
void CAVLTree::SingleLeft(PNODE &pK2)
{
//先保存K1的值
PNODE pK1 = pK2->pRight;
//先让X变成K2的右子树
pK2->pRight = pK1->pLeft;
//让K2变成K1的左子树
pK1->pLeft = pK2;
//让K1成为新的节点
pK2 = pK1;
}
//左右旋
void CAVLTree::DoubleLR(PNODE &pK3)
{
SingleLeft(pK3->pLeft);
SingleRight(pK3);
}
//右左旋
void CAVLTree::DoubleRL(PNODE &pK3)
{
SingleRight(pK3->pRight);
SingleLeft(pK3);
}
//查找
CAVLTree::PNODE CAVLTree::Find(int nFind)
{
return Find(m_pRoot, nFind);
}
//查找
(内部)
CAVLTree::PNODE CAVLTree::Find(PNODE &pNode, int nFind){if (pNode == nullptr){return false;}if (nFind > pNode->nData){return Find(pNode->pRight, nFind);}if (nFind < pNode->nData){return Find(pNode->pLeft, nFind);}}
//改变
bool CAVLTree::Change(int nFind, int nChange)
{
if (Erase(nFind))
{
return Insert(nFind);
}
return false;
}
//前序遍历
void CAVLTree::PreOrder()
{
return PreOrder(m_pRoot);
}
//前序遍历(内部)
void CAVLTree::PreOrder(const PNODE &pPreOrder)
{
if (pPreOrder == nullptr)
{
return;
}
cout << pPreOrder->nData << " ";
PreOrder(pPreOrder->pLeft);
PreOrder(pPreOrder->pRight);
}
//中序遍历
void CAVLTree::MidOrder()
{
MidOrder(m_pRoot);
}
//中序遍历(内部)
void CAVLTree::MidOrder(const PNODE &pMidOrder)
{
if (pMidOrder == nullptr)
{
return;
}
MidOrder(pMidOrder->pLeft);
cout << pMidOrder->nData << " ";
MidOrder(pMidOrder->pRight);
}
//后序遍历
void CAVLTree::LastOrder()
{
LastOrder(m_pRoot);
}
//后序遍历(内部)
void CAVLTree::LastOrder(const PNODE &pLastOrder)
{
if (pLastOrder == nullptr)
{
return;
}
LastOrder(pLastOrder->pLeft);
LastOrder(pLastOrder->pRight);
cout << pLastOrder->nData << " ";
}
//打印
void CAVLTree::PrintTree(PNODE& pNode, int nLayer)
{
if (pNode == nullptr)
{
return;
}
PrintTree(pNode->pRight, nLayer + 1);
//不同的层次,用空格来分割
for (int i = 0; i < nLayer; i++)
{
printf(" ");
}
printf("%6d\n", pNode->nData);
PrintTree(pNode->pLeft, nLayer + 1);
}
//显示
void CAVLTree::show()
{
PrintTree(m_pRoot, 0);
}
旋转示例图:
#include "stdafx.h"
#include <iostream>
#include "AVLTree.h"
using std::cout;
using std::endl;
int _tmain(int argc, _TCHAR* argv[])
{
CAVLTree obj;
for (int i = 0; i < 10; i++)
{
obj.Insert(i);
}
obj.show();
cout << "前序遍历" << endl;
obj.PreOrder();
cout << endl;
cout << "中序遍历" << endl;
obj.MidOrder();
cout << endl;
cout << "后序遍历" << endl;
obj.LastOrder();
cout << endl;
cout << "删除9" << endl;
obj.Erase(9);
obj.show();
cout << "添加88" << endl;
obj.Insert(88);
obj.show();
obj.GetHeight();
cout << "查找5,返回地址" << endl;
cout << obj.Find(5) << endl;
system("pause");
return 0;
}
演示效果(树形图的左边为根):