一个C++的平衡二叉树例子

来源:互联网 发布:飞思卡尔单片机选型 编辑:程序博客网 时间:2024/06/06 02:17


MyAVLTree.h

#pragma once#include <memory.h>// IsEmpty():若树为空,返回true,否则返回false// GetDepth():获得树的深度// Destroy():销毁一颗树// Clear():清空一棵树// GetRoot(T):返回树的根节点到T中// GetValue(T):返回指定节点T的值// PreOrderTraverse():前序遍历整棵树// InOrderTraverse():中序遍历整棵树// PostOrderTraverse():后序遍历整棵树// Insert(e): 在树中插入新节点,并将值设为e// Delete(e):将值为e的节点在树中删除class MyBiTree{public:typedef struct _NODE{_NODE* pLeft;_NODE* pRight;int    nData;}NODE,*PNODE;MyBiTree(void);~MyBiTree(void);public:bool IsEmpty(); // 判断树是否为空int  GetDepth(PNODE pNode){if (pNode==nullptr){return 0;}int nLeftDepth = GetDepth(pNode->pLeft);int nRightDepth = GetDepth(pNode->pRight);if (nLeftDepth>nRightDepth){return nLeftDepth+1;}else{return nRightDepth+1;}// return nLeftDepth>nRightDepth?// nLeftDepth:nRightDepth;}void PreOrderTraverse()//前序遍历{PreOrderTraverse(m_pRoot);printf("\n");}void MidOrderTraverse()//中序遍历{MidOrderTraverse(m_pRoot);printf("\n");}void SubOrderTraverse()//后序遍历{SubOrderTraverse(m_pRoot);printf("\n");}bool InsertEle(int nEle){return Insert(nEle,m_pRoot);}bool DeleteEle(int nEle){Delete(nEle,m_pRoot);}private:void PreOrderTraverse(PNODE pNode);void MidOrderTraverse(PNODE pNode);void SubOrderTraverse(PNODE pNode);bool AddNode(PNODE& pNode,int nEle);bool Insert(int nEle,PNODE& pNode);bool Delete(int nEle,PNODE& pNode);PNODE SingleLeftRevolve(PNODE& pk2){PNODE pk1 = pk2->pLeft;pk2->pLeft = pk1->pRight;pk1->pRight = pk2;return pk1;}PNODE DoubleLeftRevolve(PNODE& pk2){SingleRightRevolve(pk2->pLeft);return SingleLeftRevolve(pk2);}PNODE SingleRightRevolve(PNODE& pk2){PNODE pk1 = pk2->pLeft;pk2->pRight = pk1->pLeft;pk1->pLeft = pk2;return pk1;}PNODE DoubleRightRevolve(PNODE& pk2){SingleLeftRevolve(pk2->pRight);return SingleRightRevolve(pk2);}PNODE& GetMinNode(PNODE& pNode){while (pNode->pLeft!=nullptr){pNode = pNode->pLeft;}return pNode;}PNODE& GetMaxNode(PNODE& pNode){while (pNode->pRight!=nullptr){pNode = pNode->pRight;}return pNode;}private:PNODE m_pRoot;};


MyAVLTree.cpp

#include "stdafx.h"#include "MyBiTree.h"MyBiTree::MyBiTree(void):m_pRoot(nullptr){}MyBiTree::~MyBiTree(void){}//判断树是否为空bool MyBiTree::IsEmpty(){if(m_pRoot==nullptr)return true;return false;//return m_pRoot?false:true;}//二叉树的前序遍历void MyBiTree::PreOrderTraverse(PNODE pNode){//是否已经遍历到叶子节点之后if (pNode == nullptr){return ;}//访问遍历到的结点printf("%-5d",pNode->nData);//访问左子树PreOrderTraverse(pNode->pLeft);//访问右子树PreOrderTraverse(pNode->pRight);}//二叉树的中序遍历void MyBiTree::MidOrderTraverse(PNODE pNode){//是否已经遍历到叶子节点之后if (pNode == nullptr){return ;}//访问左子树MidOrderTraverse(pNode->pLeft);//访问遍历到的结点printf("%-5d",pNode->nData);//访问右子树MidOrderTraverse(pNode->pRight);}//二叉树的后序遍历void MyBiTree::SubOrderTraverse(PNODE pNode){//是否已经遍历到叶子节点之后if (pNode == nullptr){return ;}//访问左子树SubOrderTraverse(pNode->pLeft);//访问右子树SubOrderTraverse(pNode->pRight);//访问遍历到的结点printf("%-5d",pNode->nData);}bool MyBiTree::AddNode(PNODE& pNode,int nEle){pNode = new NODE;if (pNode == nullptr){return false;}memset(pNode,0,sizeof(NODE));pNode->nData = nEle;return true;}bool MyBiTree::Insert(int nEle,PNODE& pNode){//1 如果为nullptr,说明已经走到了叶子节点之后,可以添加了if (pNode == nullptr){return AddNode(pNode,nEle);}//2 假如数据比此结点数据大,说明应该插入在右子树当中if (nEle>pNode->nData){    if (false==Insert(nEle,pNode->pRight)){return false;}}//3 假如数据比此结点数据小,说明应该插入在左子树当中else if(nEle<pNode->nData){if (false == Insert(nEle,pNode->pLeft)){return false;}}//4 假如数据一样大,返回错误else{return false;}int nLeftHeight = GetDepth(pNode->pLeft);int nRightHeight = GetDepth(pNode->pRight);//进行左旋if (nLeftHeight-nRightHeight==2){//进行左单旋if(GetDepth(pNode->pLeft->pLeft)>=GetDepth(pNode->pLeft->pRight)){pNode = SingleLeftRevolve(pNode);}//进行左双旋else{pNode = DoubleLeftRevolve(pNode);}}//进行右旋else if (nRightHeight-nLeftHeight==2){if(GetDepth(pNode->pRight->pRight)>=GetDepth(pNode->pRight->pLeft)){pNode = SingleRightRevolve(pNode);}else{pNode = SingleRightRevolve(pNode);}}return true;}bool MyBiTree::Delete(int nEle,PNODE& pNode){//1 已经递归到叶子节点之后,但还没有找到数据,返回失败if (pNode==nullptr){return false;}//2 数据比此结点大,去右子树中继续删除if (nEle>pNode->nData){if (Delete(nEle,pNode->pRight)){return false;}}//3 数据比此结点小,去左子树中继续删除else if (nEle<pNode->nData){if (false == Delete(nEle,pNode->pLeft)){return false;}}//4 找到此数据了else{//4.1找的是叶子节点的情况if (pNode->pLeft==nullptr&&pNode->pRight==nullptr){//释放此结点delete pNode;pNode = nullptr;//成功return true;}//4.2找到的是非叶子节点的情况else{int nLeftHeight = GetDepth(pNode->pLeft);int nRightHeight = GetDepth(pNode->pRight);//4.2.1如果左边比右边高,应该删除左边if (nLeftHeight>nRightHeight){//寻找左边的最大值PNODE& pTempNode = GetMaxNode(pNode->pLeft);//将最大值赋值给要删除的结点pNode->nData = pTempNode->nData;//去左子树中删除找到的最大值if (false==Delete(pTempNode->nData,pNode->pLeft)){return false;}//return Delete(pTempNode->nData,pTempNode);}//4.2.2如果右边比左边高,应该删除右边else{//寻找右边的最小值PNODE& pTempNode = GetMinNode(pNode->pRight);//将最小赋值给将删除的结点pNode->nData = pTempNode->nData;//去右子树中删除找到的最小值if (false==Delete(pTempNode->nData,pNode->pRight)){return false;}//return Delete(pTempNode->nData,pTempNode);}}}int nLeftHeight = GetDepth(pNode->pLeft);int nRightHeight = GetDepth(pNode->pRight);//进行左旋if (nLeftHeight-nRightHeight==2){//进行左单旋if(GetDepth(pNode->pLeft->pLeft)>=GetDepth(pNode->pLeft->pRight)){SingleLeftRevolve(pNode);}//进行左双旋else{DoubleLeftRevolve(pNode);}}//进行右旋else if (nRightHeight-nLeftHeight==2){if(GetDepth(pNode->pRight->pRight)>=GetDepth(pNode->pRight->pLeft)){SingleRightRevolve(pNode);}else{SingleRightRevolve(pNode);}}return true;}


AVLTree.cpp

// BiTree.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "MyBiTree.h"int _tmain(int argc, _TCHAR* argv[]){MyBiTree obj;obj.InsertEle(88);obj.InsertEle(75);obj.InsertEle(62);obj.InsertEle(50);obj.InsertEle(37);obj.InsertEle(25);obj.InsertEle(12);obj.MidOrderTraverse();return 0;}

0 0