二叉树的C++实现代码

MyBiTree.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& 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;
};


MyBiTree.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)
	{    
		return Insert(nEle,pNode->pRight);
	}
	//3 假如数据比此结点数据小,说明应该插入在左子树当中
	else if(nEle<pNode->nData)
	{
		return Insert(nEle,pNode->pLeft);
	}
	//4 假如数据一样大,返回错误
	else
	{
		return false;
	}
}

bool MyBiTree::Delete(int nEle,PNODE& pNode)
{
	//1 已经递归到叶子节点之后,但还没有找到数据,返回失败
	if (pNode==nullptr)
	{
		return false;
	}
	//2 数据比此结点大,去右子树中继续删除
	if (nEle>pNode->nData)
	{
		return Delete(nEle,pNode->pRight);
	}
	//3 数据比此结点小,去左子树中继续删除
	else if (nEle<pNode->nData)
	{
		return Delete(nEle,pNode->pLeft);
	}
	//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;
				//去左子树中删除找到的最大值
				return Delete(pTempNode->nData,pNode->pLeft);
				//return Delete(pTempNode->nData,pTempNode);
			}
			//4.2.2如果右边比左边高,应该删除右边
			else
			{
				//寻找右边的最小值
				PNODE& pTempNode = GetMinNode(pNode->pRight);
				//将最小赋值给将删除的结点
				pNode->nData = pTempNode->nData;
				//去右子树中删除找到的最小值
				return Delete(pTempNode->nData,pNode->pRight);
				//return Delete(pTempNode->nData,pTempNode);
			}

		}
	}
}


BiTree.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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值