搜索/遍历/排序二叉树和反汇编的实现
前言:搜索/遍历二叉树和反汇编的实现笔记
参考文章:https://blog.csdn.net/yangmingtia/article/details/81988010
节点结构体
没有用到parent指针,因为感觉麻烦,自己不想花太多时间去调试,所有用了数据域和左右指针来写
template<class T>
class TreeNode{
public:
T element; //当前节点存储的数据
TreeNode<T>* pLeft; //指向左子节点的指针
TreeNode<T>* pRight; //指向右子节点的指针
TreeNode(T& ele){
//初始化Node节点
memset(&element, 0, sizeof(TreeNode));
//为元素赋值
memcpy(&element, &ele, sizeof(T));
pLeft = pRight = NULL;
}
};
数据域的节点
树的节点结构体中的数据域存储怪物对象
class Monster
{
public:
int ID;
int Level;
char Name[20];
public:
Monster(){
}
Monster(int ID, int Level, char* Name)
{
this->ID = ID;
this->Level = Level;
memcpy(&this->Name, Name, strlen(Name) + 1);
}
};
通过二叉树来进行遍历怪物的名称
实现代码如下:
#include "StdAfx.h"
#include<stdio.h>
#include<Windows.h>
class Monster
{
public:
int ID;
int Level;
char Name[20];
public:
Monster(){
}
Monster(int ID, int Level, char* Name)
{
this->ID = ID;
this->Level = Level;
memcpy(&this->Name, Name, strlen(Name) + 1);
}
};
template<class T>
class TreeNode{
public:
T element; //当前节点存储的数据
TreeNode<T>* pLeft; //指向左子节点的指针
TreeNode<T>* pRight; //指向右子节点的指针
TreeNode(T& ele){
//初始化Node节点
memset(&element, 0, sizeof(TreeNode));
//为元素赋值
memcpy(&element, &ele, sizeof(T));
pLeft = pRight = NULL;
}
};
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>* pNode); //返回某个节点的高度/深度
private:
void Init();
void Clear();
private:
TreeNode<T>* m_pRoot; //根结点指针
int size; //树中元素总个数
};
template<class T>
BSortTree<T>::BSortTree()
{
Init();
}
template<class T>
BSortTree<T>::~BSortTree(){
//释放所以节点空间
this->Clear();
}
template<class T>
void BSortTree<T>::Clear()
{
if(this->m_pRoot != NULL){
this->m_pRoot = this->m_pRoot->pLeft;
this->Clear();
this->m_pRoot = this->m_pRoot->pLeft;
this->Clear();
}else{
delete this->m_pRoot;
printf("%s",((T*)&this->m_pRoot->element)->Name);
this->m_pRoot = NULL;
}
}
template<class T>
void BSortTree<T>::Init()
{
Monster m1(1, 1, "刺猬");
Monster m2(2, 2, "野狼");
Monster m3(3, 3, "野猪");
Monster m4(4, 4, "士兵");
Monster m5(5, 5, "火龙");
Monster m6(6, 6, "独角兽");
Monster m7(7, 7, "江湖大盗");
//每个节点中都存储相关怪物的信息
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);
TreeNode<Monster>* n7 = new TreeNode<Monster>(m7);
//构建二叉树节点
m_pRoot = n5;
n5->pLeft = n4;
n5->pRight = n6;
n4->pLeft = n1;
n1->pRight = n2;
n6->pLeft = n3;
n3->pRight = n7;
size = 7;
/*
5
4 6
1 3
2 7
*/
}
template<class T>
TreeNode<T>* BSortTree<T>::GetRoot()
{
return m_pRoot;
}
template<class T>
int BSortTree<T>::GetDepth(TreeNode<T>* pNode)
{
if (pNode == NULL)
{
return 0;
}
else
{
//递归深度
int m = GetDepth(pNode->pLeft);
int n = GetDepth(pNode->pRight);
return (m > n) ? (m + 1) : (n + 1);
}
}
template<class T>
void BSortTree<T>::PreOrderTraverse(TreeNode<T>* pNode)
{
//前序遍历所有怪物,列出怪的名字
if(pNode != NULL){
printf("%s %d\n",((T*)&pNode->element)->Name,((T*)&pNode->element)->ID);
PreOrderTraverse(pNode->pLeft);
PreOrderTraverse(pNode->pRight);
}
//if(pNode->pLeft != NULL){
//InOrderTraverse(pNode->pRight);
//}
}
template<class T>
void BSortTree<T>::InOrderTraverse(TreeNode<T>* pNode)
{
//中序遍历所有怪物,列出怪的名字
if(pNode != NULL){
InOrderTraverse(pNode->pLeft); //
printf("%s %d\n",((T*)&pNode->element)->Name,((T*)&pNode->element)->ID);
InOrderTraverse(pNode->pRight); //
}
}
template<class T>
void BSortTree<T>::PostOrderTraverse(TreeNode<T>* pNode)
{
//后序遍历所有怪物,列出怪的名字
if(pNode != NULL){
PostOrderTraverse(pNode->pLeft); //
PostOrderTraverse(pNode->pRight); //
printf("%s %d\n",((T*)&pNode->element)->Name,((T*)&pNode->element)->ID);
}
}
int main(){
BSortTree<Monster>* myTree = new BSortTree<Monster>();
myTree->PreOrderTraverse(myTree->GetRoot());
printf("=========================================\n");
myTree->InOrderTraverse(myTree->GetRoot());
printf("=========================================\n");
myTree->PostOrderTraverse(myTree->GetRoot());
printf("=========================================\n");
printf("%d",myTree->GetDepth(myTree->GetRoot()));
return 0;
}
搜索二叉树增加/删除/搜索相应的节点
实现代码如下:
#include "StdAfx.h"
#define SUCCESS 1 // 执行成功
#define ERROR -1 // 执行失败
template<class T>
class TreeNode{
public:
T element; //当前节点存储的数据
TreeNode<T>* pLeft; //指向左子节点的指针
TreeNode<T>* pRight; //指向右子节点的指针
TreeNode<T>* pParent; //指向父结点的指针
TreeNode(T& ele){
//初始化Node节点
memset(&element,0,sizeof(TreeNode));
//为元素赋值
memcpy(&element,&ele,sizeof(T));
pLeft = pRight = pParent = NULL;
}
//重载== 比较两结点是否相等
bool operator==(TreeNode<T>* node){
return node->element == element?true:false;
}
/*
TreeNode<T> operator=(TreeNode<T>* node){
this->element = node->element;
return *this;
}
*/
};
template<class T>
class BSortTree{
public:
BSortTree(); //构造函数
~BSortTree(); //析构函数
public: //判断树是否为空
bool IsEmpty(); //新增节点
DWORD Insert(T element); //删除节点
void Delete(T element);
TreeNode<T>* Search(T element); //查找节点
void InOrderTraverse(TreeNode<T>* pNode); //中序遍历
void PreOrderTraverse(TreeNode<T>* pNode); //前序遍历
void PostOrderTraverse(TreeNode<T>* pNode); //后序遍历
private:
TreeNode<T>* GetMaxNode(TreeNode<T>* pNode); //获取以pNode为根的最大节点
TreeNode<T>* GetMinNode(TreeNode<T>* pNode); //获取以pNode为根的最小节点
TreeNode<T>* SearchNode(TreeNode<T>* pNode,T element); //获取以pNode为根的最小节点
DWORD InsertNode(T element, TreeNode<T>* pNode); //新增节点
void DeleteNode(T element, TreeNode<T>* pNode); //删除节点
void Clear(TreeNode<T>* pNode); //清空所有节点
private:
TreeNode<T>* m_pRoot; //根结点指针
int size; //树中元素总个数
};
template<class T>
BSortTree<T>::BSortTree()
{
m_pRoot = NULL;
size = 0;
}
template<class T>
BSortTree<T>::~BSortTree(){
Clear(m_pRoot);
}
template<class T>
DWORD BSortTree<T>::Insert(T element){
//如果根节点为空
if ( !m_pRoot )
{
m_pRoot = new TreeNode<T>(element);
size++;
return SUCCESS;
}
//如果根节点不为空
return InsertNode(element, m_pRoot);
}
template<class T>
DWORD BSortTree<T>::InsertNode(T element, TreeNode<T>* pNode)
{
//将元素封装到节点中
TreeNode<T>* pNewNode = new TreeNode<T>(element);
//如果element == 当前节点 直接返回
if(element == pNode->element)
{
return SUCCESS;
}
//如果pNode的左子节点为NULL 并且element < 当前节点
if(pNode->pLeft == NULL && element < pNode->element)
{
pNode->pLeft = pNewNode;
pNewNode->pParent = pNode;
size++;
return SUCCESS;
}
//如果pNode的右子节点为NULL 并且element > 当前节点
if(pNode->pRight == NULL && element > pNode->element){
pNode->pRight = pNewNode;
pNewNode->pParent = pNode;
size++;
return SUCCESS;
}
//如果element<当前节点 且当前节点的左子树不为空
if(element < pNode->element)
{
InsertNode(element,pNode->pLeft);
}
else
{
InsertNode(element,pNode->pRight);
}
return SUCCESS;
}
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>
bool BSortTree<T>::IsEmpty()
{
return size==0?true:false;
}
template<class T>
TreeNode<T>* BSortTree<T>::Search(T element)
{
return SearchNode(m_pRoot, element);
}
template<class T>
TreeNode<T>* BSortTree<T>::SearchNode(TreeNode<T>* pNode,T element)
{
if(pNode == NULL) //如果节点为NULL
{
return NULL;
}
else if(element == pNode->element) //如果相等
{
return pNode;
} //如果比节点的元素小 向左找
else if(element < pNode->element)
{
return SearchNode(pNode->pLeft,element);
}
else //如果比节点的元素大 向右找
{
return SearchNode(pNode->pRight,element);
}
}
//获取当前节点作为子树下的最小节点元素
template<class T>
TreeNode<T>* BSortTree<T>::GetMinNode(TreeNode<T>* pNode){
if(pNode->pLeft == NULL){
return pNode;
}else{
return this->GetMinNode(pNode->pLeft);
}
}
template<class T>
void BSortTree<T>::Delete(T element)
{
TreeNode<T>* p_new_treeNode = this->Search(element);
if(p_new_treeNode == NULL)
{
printf("not found the treeNode,so searchNode failed! \n");
}else{
DeleteNode(element, p_new_treeNode);
}
}
/*
情况1:叶子节点
1、删除该节点
2、将父节点(左或者右)指针置NULL
情况2:只有一个子树
1、删除该节点
2、将父节点(左或者右)指针指向子树
情况3:左右子树都有
1、用右子树最小的节点取代源节点
2、再递归删除最小节点
*/
template<class T>
void BSortTree<T>::DeleteNode(T element,TreeNode<T>* pNode)
{
TreeNode<T>* p_parent_treeNode;
TreeNode<T>* p_min_treeNode;
T min_element = 0;
p_parent_treeNode = pNode->pParent; // parent pointer
if(pNode->pRight == NULL && pNode->pLeft == NULL){
//printf("1111111111111\n");
if (p_parent_treeNode->pLeft == pNode){
p_parent_treeNode->pLeft = NULL;
//1、删除该节点
delete pNode;
//2、将父节点(左或者右)指针置NULL
p_parent_treeNode->pLeft = NULL;
pNode = NULL;
}else{
p_parent_treeNode->pRight = NULL;
//1、删除该节点
delete pNode;
//2、将父节点(左或者右)指针置NULL
p_parent_treeNode->pRight = NULL;
pNode = NULL;
}
}else if(pNode->pLeft != NULL && pNode->pRight == NULL){
//printf("22222222222222\n");
//当被删除的节点只有左节点存活的时候
p_parent_treeNode->pLeft = pNode->pLeft;
pNode->pLeft->pParent = p_parent_treeNode;
delete pNode;
pNode = NULL;
}else if(pNode->pLeft == NULL && pNode->pRight != NULL){
//printf("3333333333333333\n");
//当被删除的节点只有右节点存活的时候
p_parent_treeNode->pRight = pNode->pRight;
pNode->pRight->pParent = p_parent_treeNode;
delete pNode;
pNode = NULL;
}else{
//printf("44444444444444444\n");
//1、用右子树最小的节点取代源节点
p_min_treeNode = GetMinNode(pNode->pRight);
pNode->element = p_min_treeNode->element;
p_parent_treeNode = p_min_treeNode->pParent;
if(p_min_treeNode->pLeft != NULL && p_min_treeNode->pRight == NULL){ // 被删除的节点的左节点不为空 右节点为空
p_parent_treeNode->pLeft = p_min_treeNode->pLeft;
delete p_min_treeNode;
p_min_treeNode = NULL;
}else if(p_min_treeNode->pLeft == NULL && p_min_treeNode->pRight != NULL){ // 被删除的节点的左节点为空 右节点不为空
p_parent_treeNode->pLeft = p_min_treeNode->pRight;
delete p_min_treeNode;
p_min_treeNode = NULL;
}else{ // 被删除的节点的左节点为空 右节点为空
delete p_min_treeNode;
p_min_treeNode = NULL;
}
}
}
//insert
void TestInsert(){
//12 8 5 9 17 15 13
/*
12
/ \
8 17
/ \ /
5 9 15
/
13
*/
BSortTree<int> tree;
tree.Insert(12);
tree.Insert(8);
tree.Insert(5);
tree.Insert(9);
tree.Insert(17);
tree.Insert(15);
tree.Insert(13);
}
//search
void TestSerch(){
//12 8 5 9 17 15 13
/*
12
/ \
8 17
/ \ /
5 9 15
/
13
*/
BSortTree<int> tree;
tree.Insert(15);
tree.Insert(5);
tree.Insert(3);
tree.Insert(12);
tree.Insert(10);
tree.Insert(13);
tree.Insert(6);
tree.Insert(7);
tree.Insert(16);
tree.Insert(20);
tree.Insert(18);
tree.Insert(23);
TreeNode<int>* p = tree.Search(10);
printf("%d \n",p->element);
}
//delete
void TestDelete(){
//12 8 5 9 17 15 13
/*
12
/ \
8 17
/ \ /
5 9 15
/
13
*/
BSortTree<int> tree;
tree.Insert(15);
tree.Insert(5);
tree.Insert(3);
tree.Insert(12);
tree.Insert(10);
tree.Insert(13);
tree.Insert(6);
tree.Insert(7);
tree.Insert(16);
tree.Insert(20);
tree.Insert(18);
tree.Insert(23);
tree.Delete(5);
TreeNode<int>* p = tree.Search(10);
printf("%d \n",p->element);
printf("%d \n",p->pLeft->element);
//printf("%d \n",p->pRight->element);
}
int main(){
//TestSerch();
TestDelete();
return 0;
}