平衡二叉树

来源:互联网 发布:知柏地黄丸的功效 编辑:程序博客网 时间:2024/06/04 00:21

此为头文件.h

#pragma onceclass 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,K2pK2 = 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;}

演示效果(树形图的左边为根):



0 0