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; }