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