滴水二叉树实现详细注释

#include "stdafx.h"
#include "windows.h"

#define SUCCESS           			  1 // 执行成功	
#define ERRORR			 -1 // 执行失败	


//基础怪物模板
class Monster {

public:
	int Id;  //怪物编号
	char Name[20];//名字
	int Level;//等级
	
public:
	Monster() {};//构造 ,默认怪物
	Monster(int Id, char* Name, int Level);   //怪物参数

	bool Monster::operator<(const Monster& p) {
		return  this->Id < p.Id ? true : false;
	}
	bool Monster::operator>(const Monster& p) {
		return  this->Id > p.Id ? true : false;
	}
	bool Monster::operator==(const Monster& p) {
		return   this->Id == p.Id ? true : false;
	}



};


Monster::Monster(int Id, char* Name, int Level) {
	this->Id = Id;
	memcpy(&this->Name, Name, strlen(Name)+1);
	this->Level=Level;
}


template<class T>
class TreeNode {
public:
	T element; //节点数据
	TreeNode<T>* pLeft; //左树指针
	TreeNode<T>* pRight;//右树指针
	TreeNode<T>* pParent;//父节点指针

	TreeNode(T& ele) {
		//初始化
		memset(&element, 0, sizeof(TreeNode));
		memcpy(&element, &ele, sizeof(T));
		pLeft = pRight = NULL;
			
	}
	/*
	bool operator<(const TreeNode<T>& p) {
		return  this->element<p->element  ? true : false;
	}
	bool operator>(const TreeNode<T>& p) {
		return this->element>p->element ? true : false;
	}
	bool operator==(const TreeNode<T>& p) {
		return this->element == p->element ? true : false;
	}*/
};

template<class T>
class BsortTree {
public:
	BsortTree();
	~BsortTree();
public:
	void InOrderTraverse(TreeNode<T>* pNode); //中序遍历
	void PreOrderTraverse(TreeNode<T>* pNode);//前序遍历
	void PostOrderTraverse(TreeNode<T>* pNode);//后序遍历
	TreeNode<T>* GetRoot();//返回根节点
	int GetDepth(TreeNode<T>* Node);// 返回当前节点高度
	bool IsEmpty();//判断树是否为空
	DWORD Insert(T element);//新增节点
	void Delete(T element);//删除节点
	
private:
	void Init();//初始化一些数值
	void clear(TreeNode<T>* pNode);//删除所有节点
	DWORD InsertNode(TreeNode<T>* pNode, T element);
	TreeNode<T>* DeleteNode(T element, TreeNode<T>* pNode);
	TreeNode<T>* GetMinNode(TreeNode<T>* pNode);//获取以pNode为根的最小节点,注:删除NODE下,寻找PNODE右树的最小节点顶到NODE节点上。再删除原最小节点
	TreeNode<T>* GetMaxNode(TreeNode<T>* pNode);//获取以pNode为根的最大节点
private:
	TreeNode<T>* pRootNode; //根节点指针
	int size;//树中元素总数

};

template<class T>
TreeNode<T>* BsortTree<T>::GetMinNode(TreeNode<T>* pNode) {
	TreeNode<T>* pMin = NULL;
	if (pNode!=NULL) {
		int data = pNode->element;//说一下,这里为什么不用T类型,因为T代表整个类型大小,但是我们只需要NODE头4个字节的数据,这里有一点不通用,节点的头四个字节数据类型被限制了。
		if (data>=pNode->element) {
			pMin = (TreeNode<T>*)pNode->element;//把下一个比较小的节点存起来
		}
		GetMinNode(pNode->pLeft); //这里为什么用pNode->pLeft呢,因为根据左树节点比根树节点小。
		return pMin;
	}
}

template<class T>
TreeNode<T>* BsortTree<T>::DeleteNode(T element, TreeNode<T>* pNode) {
	if (pRootNode == NULL) {
		return NULL;
	}
	else if (element == pNode->element)
		{
		if (pNode->pLeft != NULL && pNode->pRight == NULL) 
		{//左子树
			TreeNode<T>* pPt = pNode->pParent;//拿到当前节点的父节点
			pPt->pLeft = pNode->pLeft;
			delete pNode;
		}
		else if (pNode->pLeft = NULL && pNode->pRight != NULL) 
		{//右子树
			TreeNode<T>* pPt = pNode->pParent;//拿到当前节点的父节点
			pPt->pRight = pNode->pRight;
			delete pNode;
		}
		else if (pNode->pLeft == NULL&&pNode->pRight == NULL) 
		{//左右树均为空
			TreeNode<T>* p;
			p = pNode->pParent;
			if (p->pLeft != NULL&&p->pRight == NULL) {//这里实际意义就是看当前节点在父节点的左边还是右边
				delete p->pLeft;
				p->pLeft = NULL;
			}
			if (p->pLeft == NULL&&p->pRight != NULL) {
				delete p->pRight;
				p->pRight = NULL;
			}
			//
			delete p->pRight;
			p->pRight = NULL;     //这两行就是代表子节点一样,且不为空,删除哪个都一样。
		}
		else if (pNode->pLeft != NULL&&pNode->pRight != NULL) {//左右子树均不为空
			TreeNode<T>* pCurrent = pNode->pRight;
			TreeNode<T>* pMin = GetMinNode(pNode->pRight);//GetMinNode是一个递归函数,返回NODE子树里的最小节点
			pNode->element = (int)pMin;//把最小的节点元素抬到Pnode节点这里来
			DeleteNode(pNode->element, pCurrent);//此时此刻,Pnode已经替换为最小节点的元素了,
												 //那么只需要删除pCurrent(pNode->pRight)下的子树最小节点就可以了,这里用的递归。

			}
	}
		else if (element > pNode->element) 
		{//Element 大于Pnode的E。那么就往Pnode右树开始找
			DeleteNode(element, pNode->pRight);

		}
		else
		{
			DeleteNode(element, pNode->pLeft);
		}
		return NULL;
	

}


template<class T>
void BsortTree<T>::Delete(T element) {
	DeleteNode(T element, TreeNode<T>* pNode);
}






template<class T>
DWORD BsortTree<T>::InsertNode(TreeNode<T>* pNode, T element) {
	//建立一个节点,把元素存进去
	TreeNode<T>* pElement = new TreeNode<T>(element);
	//如果元素等于当前节点就直接返回
	if (pNode->element==element  ) {
		return SUCCESS;
	}
	//如果pnode节点的左子节点为null且element<pnode节点
	if (pNode->pLeft == NULL && pNode->element>element  ) {
		pNode->pLeft = pElement;
		size++;
		return SUCCESS;
	}
	//如果pnode节点的右子节点为null且element>pnode节点
	if (pNode->pRight == NULL&&pNode->element<element  ) {
		pNode->pRight = pElement;
		size++;
		return SUCCESS;
	}
	//pnode左节点不为空且element<pnode节点----------此处为递归
	if (pNode->element>element) {

		InsertNode(pNode->pLeft, element);
	}
	else {
		InsertNode(pNode->pRight, element);
	}
}


template<class T>
DWORD BsortTree<T>::Insert(T element) {
	if (!pRootNode) {//如果根节点为空
		pRootNode = new TreeNode<T>(element);
		size++;
		return SUCCESS;
	}
	return InsertNode(pRootNode, element);


}
template<class T>
bool BsortTree<T>::IsEmpty() {
	return size == 0 ? true : false;
}

template<class T>
BsortTree<T>::~BsortTree() {
	//循环删除节点元素
	clear(pRootNode);
	

}

template<class T>
void BsortTree<T>::clear(TreeNode<T>* pNode) {
	if (pNode != NULL) {
		clear(pNode->pLeft);
		clear(pNode->pRight);
		delete pNode;
		pNode = NULL;
	}

}

template<class T>
BsortTree<T>::BsortTree() {
	Init();
}


template<class T>// 返回当前节点高度,Node
int BsortTree<T>::GetDepth(TreeNode<T>* Node) {
	if (Node == NUll) {
		return 0;
	}
	else
	{
		int Left = GetDepth(Node->pLeft);
		int Right = GetDepth(Node->pRight);
		return (Left > Right) ? (Left + 1) : (Right + 1);
	}

}


//获取根节点
template<class T>
 TreeNode<T>* BsortTree<T>::GetRoot() {
	return pRootNode;
}





//中序遍历
template<class T>
void BsortTree<T>::InOrderTraverse(TreeNode<T>* pNode) {



	if (pNode == NULL)
	{
		return;
	}
	else
	{
		InOrderTraverse(pNode->pLeft);
		printf("%d\n", pNode->element);
		InOrderTraverse(pNode->pRight);
	}

}

//前序遍历
template<class T>//前序遍历
void BsortTree<T>::PreOrderTraverse(TreeNode<T>* pNode) {
	if (pNode != NULL) {
		printf("%d\n", pNode->element);
		PreOrderTraverse(pNode->pLeft);
		PreOrderTraverse(pNode->pRight);
	}
}

//后序遍历
template<class T>
void BsortTree<T>::PostOrderTraverse(TreeNode<T>* pNode) {
	if (pNode != NULL) {
		PostOrderTraverse(pNode->pLeft);
		PostOrderTraverse(pNode->pRight);
		printf("%d\n", pNode->element);
	}

}
	




template<class T>
void BsortTree<T>::Init() {

	
	Monster m1(1, "混世魔王",50);
	Monster m2(2, "金斯尔", 100);
	Monster m3(3, "游离", 74);
	Monster m4(4, "尔康", 56);
	Monster m5(5, "二讹", 88);
	Monster m6(6, "传奇", 999);
	TreeNode<Monster>* n1 = new TreeNode<Monster>(m1);
	TreeNode<Monster>* n2 = new TreeNode<Monster>(m2);
	TreeNode<Monster>* n3 = new TreeNode<Monster>(m3);
	TreeNode<Monster>* n4 = new TreeNode<Monster>(m4);
	TreeNode<Monster>* n5 = new TreeNode<Monster>(m5);
	TreeNode<Monster>* n6 = new TreeNode<Monster>(m6);

	pRootNode = n3;
	n3->pLeft = n2;
	n3->pRight = n1;
	n1->pLeft = n4;
	n1->pRight = n5;
	//n5->pRight = n6;
	//size = 6;
	
	/*
	 3
  2     1
      4    5
	          6
	
	
	*/

}

int main()
{
	
	
	BsortTree<Monster>* p = new BsortTree<Monster>();
	p->InOrderTraverse(p->GetRoot());
	Monster m6(6, "传奇", 999);
	p->Insert(m6);
	printf("\n");
	p->InOrderTraverse(p->GetRoot());
	getchar();
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1讲:2015-01-12(进制01) 第2讲:2015-01-13(进制02) 第3讲:2015-01-14(数据宽度-逻辑运算03) 第4讲:2015-01-15(通用寄存器-内存读写04) 第5讲:2015-01-16(内存寻址-堆栈05) 第6讲:2015-01-19(EFLAGS寄存器06) 第7讲:2015-01-20(JCC) 第8讲:2015-01-21(堆栈图) 第8讲:2015-01-21(宝马问题) 第9讲:2015-01-22(堆栈图2) 第10讲:2015-01-23(C语言01_后半段) 第10讲:2015-01-23(C语言完整版) 第11讲:2015-01-26(C语言02_数据类型) 第12讲:2015-01-27(C语言03_数据类型_IF语句) 第13讲:2015-01-28(C语言04_IF语句逆向分析上) 第14讲:2015-01-28(C语言04_IF语句逆向分析下) 第15讲:2015-01-29(C语言04_正向基础) 第16讲:2015-01-30(C语言05_循环语句) 第17讲:2015-02-02(C语言06_参数_返回值_局部变量_数组反汇编) 第18讲:2015-02-02(2015-01-30课后练习) 第19讲:2015-02-03(C语言07_多维数组) 第20讲:2015-02-03(2015-02-02课后练习) 第21讲:2015-02-04(C语言08_结构体) 第22讲:2015-02-05(C语言09_字节对齐_结构体数组) 第23讲:2015-02-06(C语言10_Switch语句反汇编) 第24讲:2015-02-26(C语言11_指针1) 第25讲:2015-02-27(C语言11_指针2) 第26讲:2015-02-28(C语言11_指针3) 第27讲:2015-02-28(C语言11_指针4) 第28讲:2015-03-02(C语言11_指针5) 第29讲:2015-03-03(C语言11_指针6) 第30讲:2015-03-04(C语言11_指针7) 第31讲:2015-03-06(C语言11_指针8) 第32讲:2015-03-09(位运算) 第33讲:2015-03-10(内存分配_文件读写) 第34讲:2015-03-11(PE头解析_手动) 第35讲:2015-03-12(PE头字段说明) 第36讲:2015-03-13(PE节表) 第37讲:2015-03-16(FileBuffer转ImageBuffer) 第38讲:2015-03-17(代码节空白区添加代码) 第39讲:2015-03-18(任意节空白区添加代码) 第40讲:2015-03-19(新增节添加代码) 第41讲:2015-03-20(扩大节-合并节-数据目录) 第42讲:2015-03-23(静态连接库-动态链接库) 第43讲:2015-03-24(导出表) 第44讲:2015-03-25(重定位表) 第45讲:2015-03-26(移动导出表-重定位表) 第46讲:2015-03-27(IAT表) 第47讲:2015-03-27(导入表) 第48讲:2015-03-30(绑定导入表) 第49讲:2015-03-31(导入表注入) 第50讲:2015-04-01(C++ this指针 类 上) 第51讲:2015-04-01(C++ this指针 类 下) 第52讲:2015-04-02(C++ 构造-析构函数 继承) 第53讲:2015-04-03(C++ 权限控制) 第54讲:2015-04-07(C++ 虚函数表) 第55讲:2015-04-08(C++ 动态绑定-多态-上) 第56讲:2015-04-08(C++ 动态绑定-多态-下) 第57讲:2015-04-09(C++ 模版) 第58讲:2015-04-10(C++ 引用-友元-运算符重载) 第59讲:2015-04-13(C++ new-delete-Vector) 第60讲:2015-04-14(C++Vector实现) 第61讲:2015-04-15(C++链表) 第62讲:2015-04-16(C++链表实现) 第63讲:2015-04-16(C++二叉树) 第64讲:2015-04-17(C++二叉树实现) 第65讲:2015-04-20(Win32 宽字符) 第66讲:2015-04-21(Win32 事件-消息-消息处理函数) 第67讲:2015-04-22(Win32 ESP寻址-定位回调函数-条件断点) 第68讲:2015-04-23(Win32 子窗口-消息处理函数定位) 第69讲:2015-04-24(Win32 资源文件-消息断点) 第70讲:2015-04-27(Win32 提取图标-修改标题) 第71讲:2015-04-28(Win32 通用控件-VM_NOTIFY) 第72讲:2015-04-29(Win32 PE查看器-项目要求) 项目一:PE查看器 开发周期(5天) 需求文档 第73讲:2015-05-07(Win32 创建线程) 第74讲:2015-05-08(Win32 线程控制_CONTEXT) 第75讲:2015-05-11(Win32 临界区) 第76讲:2015-05-12(Win32 互斥体) 第77讲:2015-05-13(Win32 事件) 第78讲:2015-05-14(Win32 信号量) 第79讲:2015-05-15(Win32 线程同步与线程互斥) 第80讲:2015-05-18(Win32 进程创建_句柄表) 第81讲:2015-05-20(Win32 以挂起形式创建进程) 第82讲:2015-05-21(Win32 加密壳_项目说明) 项目二:加密壳 开发周期(5天) 需求文档 第83讲:2015-05-28(Win32 枚举窗口_鼠标键盘事件) 第84讲:2015-05-29(Win32 CE练习) 第85讲:2015-06-01(Win32 OD练习) 第86讲:2015-06-03(Win32 ShellCode_远程线程注入) 第87讲:2015-06-04(Win32 加载EXE_模块隐藏) 第88讲:2015-06-09(Win32 IAT_HOOK) 第89讲:2015-06-10(Win32 InlineHook) 第90讲:2015-06-11(Win32 进程通信) 第91讲:2015-06-11(Win32 进程监控_项目说明) 项目三:进程监控 开发周期(5天) 需求文档 第92讲:2015-06-15(硬编码_01) 第93讲:2015-06-16(硬编码_02) 第94讲:2015-06-17(硬编码_03) 第95讲:2015-06-18(硬编码_04) 第96讲:2015-06-19(硬编码_05)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值