完整类实现:构造,析构,遍历二叉树

根据前面一个博文内容已经讲述了如何根据两种遍历方式进行构建二叉树

这里利用递归方式遍历二叉树,递归方式比较简单,后续补充其余非递归方式

再此主要是完善类的使用:

其中重点在于:接口定义

二叉树的析构删除

以及类成员变量中如果有指针,同时涉及复制构造函数和赋值操作符函数时需要用到的智能指针

如果接口方面定义不够好,还望包涵

如果有对智能指针不理解的地方,可以移步 http://blog.csdn.net/xietingcandice/article/details/39670269

.h文件

#include <iostream>
#include <xtr1common>
#include <stack>
using namespace std;

struct BinaryTreeNode
{
	int Value;
	BinaryTreeNode * pLeft;
	BinaryTreeNode * pRight;
	BinaryTreeNode()
	{
		Value = 0;
		pLeft = NULL;
		pRight = NULL;
	}
};

BinaryTreeNode* ReconstructTree(int *startBackorder,int *endBackorder,int *startInorder,int *endInorder);
void DeleteRoot(BinaryTreeNode *pRoot);
class ScanBinaryTreeNode;
//<因为遍历的类中出现了指针,为了防止copy函数和赋值操作符出现内存泄露定义智能指针对应的类
class BinaryRoot
{
	friend class ScanBinaryTreeNode;  //<友元结构
	BinaryTreeNode *mpRoot;
    size_t mUse;
	BinaryRoot(	BinaryTreeNode *pRoot):mpRoot(pRoot),mUse(1) {}  //<初始化为1
	BinaryRoot():mpRoot(NULL),mUse(0){};//<默认构造函数
    ~BinaryRoot();
};
class ScanBinaryTreeNode
{
public:
	ScanBinaryTreeNode(int *startBackOrder,int *endBackOrder, int *startInOrder,int *endInOrder);
	ScanBinaryTreeNode(){};
	ScanBinaryTreeNode(const ScanBinaryTreeNode &CopyTemp);
	ScanBinaryTreeNode& operator = (const ScanBinaryTreeNode &CopyTemp);
	~ScanBinaryTreeNode();
	void ScanPreOrder();
	void ScanInOrder();
	void ScanBackOrder();
private:
	BinaryRoot* mpRootNode;
};
</span>

.c文件:

<span style="font-size:14px;">#include"BinaryTree.h"
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>

 BinaryTreeNode* ReconstructTree(int *startBackorder,int *endBackorder,int *startInorder,int *endInorder)//<根据后续和中序遍历构建二叉树
{
	BinaryTreeNode * root = new BinaryTreeNode;
	root->Value = * endBackorder;
	if (startBackorder == endBackorder) //<满足条件返回对应的根节点的值
	{
		if (startInorder == endInorder && (*startInorder == *startBackorder))
		{
			return root;
		}
		else
		{
			throw std::exception("Invalid input");
		}
	}
	int * rootInoder = startInorder;
	while ((rootInoder <= endInorder) && (*rootInoder != root->Value))
	{
		rootInoder++;
	}
	if (rootInoder > endInorder)
	{
		throw std::exception("Invalid input");
	}
	int leftLength = rootInoder-startInorder;
	if (leftLength > 0)
	{
		root->pLeft = ReconstructTree(startBackorder,startBackorder+leftLength-1,startInorder,rootInoder-1);
	}
	if ((endBackorder-startBackorder) > leftLength)
	{
		root->pRight = ReconstructTree(startBackorder+leftLength,endBackorder-1,rootInoder+1,endInorder);
	}
	return root;
}
void DeleteRoot(BinaryTreeNode *pRoot) //<根据根节点删除整棵树
 {
	 if(pRoot == NULL)
	 {
		 return;
	 }
	 BinaryTreeNode * pLeft = pRoot->pLeft;
	 BinaryTreeNode * pRight = pRoot->pRight;
	 delete pRoot;
     pRoot = NULL;
	 if(pLeft)
	 {
		 DeleteRoot(pLeft);
	 }
	 if(pRight)
	 {
		 DeleteRoot(pRight);
	 }
	 return;
 }
BinaryRoot::~BinaryRoot()
    {
		DeleteRoot(mpRoot);
    }
ScanBinaryTreeNode::ScanBinaryTreeNode(int *startBackOrder,int *endBackOrder, int *startInOrder,int *endInOrder)
{
		BinaryTreeNode *node = ReconstructTree(startBackOrder,endBackOrder,startInOrder,endInOrder);
		mpRootNode = new BinaryRoot(node); //<初始化一个指向根节点的指针
}
ScanBinaryTreeNode::ScanBinaryTreeNode(const ScanBinaryTreeNode &CopyTemp)
{
	mpRootNode = CopyTemp.mpRootNode;
	++mpRootNode->mUse;
}
ScanBinaryTreeNode::~ScanBinaryTreeNode()
{
	if((--mpRootNode->mUse) == 0) //<指针没有对象的时候进行删除
	{
		delete mpRootNode;
		mpRootNode = NULL;
	}
}
ScanBinaryTreeNode& ScanBinaryTreeNode::operator = (const ScanBinaryTreeNode &CopyTemp)
{
	++ CopyTemp.mpRootNode->mUse;  //
    if ( -- mpRootNode->mUse == 0)
		delete mpRootNode;
    mpRootNode = CopyTemp.mpRootNode;
    return *this;
}
void PreOrder(BinaryTreeNode *pRoot)
{
	if(pRoot == NULL)
	{
		return;
	}
	printf("%d ",pRoot->Value);
	BinaryTreeNode *pLeft = pRoot->pLeft;
	BinaryTreeNode *pRight = pRoot->pRight;
	if(pLeft)
	{
		PreOrder(pLeft);
	}
	if(pRight)
	{
		PreOrder(pRight);
	}
	return;

}
void BackOrder(BinaryTreeNode *pRoot)
{
	if(pRoot == NULL)
	{
		return;
	}
	BinaryTreeNode *pLeft = pRoot->pLeft;
	BinaryTreeNode *pRight = pRoot->pRight;
	if(pLeft)
	{
		BackOrder(pLeft);
	}
	if(pRight)
	{
		BackOrder(pRight);
	}
	printf("%d ",pRoot->Value);
	return;

}
void InOrder(BinaryTreeNode *pRoot)
{
	if(pRoot == NULL)
	{
		return;
	}
	BinaryTreeNode *pLeft = pRoot->pLeft;
	BinaryTreeNode *pRight = pRoot->pRight;
	if(pLeft)
	{
		InOrder(pLeft);
	}
	printf("%d ",pRoot->Value);
	if(pRight)
	{
		InOrder(pRight);
	}
	return;

}
void ScanBinaryTreeNode::ScanPreOrder()
{
	PreOrder(mpRootNode->mpRoot);
}
void ScanBinaryTreeNode::ScanBackOrder()
{
	BackOrder(mpRootNode->mpRoot);
}
void ScanBinaryTreeNode::ScanInOrder()
{
	InOrder(mpRootNode->mpRoot);
}
void Order()
{
	int BackArry[8] = {7,4,2,5,8,6,3,1};
	int MiddleArry[8] = {4,7,2,1,5,3,8,6};
	if (BackArry == NULL || MiddleArry == NULL)
	{
		return;
	}
	ScanBinaryTreeNode root(BackArry,BackArry+7,MiddleArry,MiddleArry+7);
	ScanBinaryTreeNode root1 = root;
	ScanBinaryTreeNode root2(root1);
	ScanBinaryTreeNode root3(root);
	root.ScanBackOrder();
	printf("\n");
	root.ScanInOrder();
	printf("\n");
	root.ScanPreOrder();
}
int main()
{
	Order();
	//int* i = new int;
	_CrtDumpMemoryLeaks();
	return 0;
}
</span>
时间: 2024-08-08 01:10:21

完整类实现:构造,析构,遍历二叉树的相关文章

java构造和遍历二叉树

[分析] 二叉树的结构:根节点.左子树.右子树.其中左子树的值必须小于根节点,右子树的值必须大于根节点.构造这种树结构,就是创建一个类,并提供一个方法,当给定一个值时,它能够自动创建节点并自动挂到二叉树的合适位置. 二叉树的遍历:分为先序遍历.中序遍历和后序遍历.先序遍历:根.左.右. 中需遍历:左.根.右. 后续遍历:左.右.根. 二叉树的应用:加密解密.文件压缩.快速查询.快速遍历等. 1.构造二叉树的节点对象,并提供插入方法. 1 private int data; //存放节点数据 2

C++ 类、构造析构、深拷贝

1st,感性理解类的思想,就是把数据和对数据的操作打包在一块儿,设计类的时候要 想好数据部分和 要进行的操作.以下是时间类的示意,时间包含时分秒,Time为构造函数,该类支持的操作就是设置时间和读取时间,static类型记录对象数量,static机制查询相关书籍. //Time.h #ifndef Time_h #define Time_h class Time { public: Time(int h = 0, int m = 0, int s = 0); void SetTime(int,

Delphi2010新发现-类的构造和析构函数功能

Delphi2010发布了. 虽然凭着对Delphi的热爱第一时间就安装了,但是现在可能是年纪大了,对新事物缺乏兴趣了.一直都没有仔细研究. 今天有点时间试了一下新功能. 本来C#和Delphi.NET是支持类的构造函数/析构函数的(注意不是实例的构造和析构).也就是在模块初始化/卸载的时候会调用. 这样有很多好处,比如说类的静态变量的初始化什么的都可以在这里做. Delphi For Win32对这方面的需求还不是很大. 第一个原因.历史上旧版Delphi不支持静态变量.只能用Unit的全局变

二叉树的构造_遍历_求数高和求节点数

1 //手工构造一颗二叉树 ,并给出递归和非递归2类7种遍历方法,树高,节点数求法和逆时针90度显示二叉树 2 //注意本文中2个 typename的使用层次 3 //递归遍历容易溢栈 4 #include <cstdlib> 5 #include <iostream> 6 #include <queue> //用到队列时需要包含此文件 7 #include <stack> //用到栈时需要包含此文件 8 9 using namespace std; 10

C++ 根据前序遍历序列和中序遍历序列可以构造唯一的二叉树

文章转载自http://blog.csdn.net/touzani/article/details/1637195 根据前序遍历序列和中序遍历序列可以构造唯一的二叉树. 假设序列为string型 根据前序遍历的特点, 知前序序列(Pre)的首个元素(Pre[0])为根(root), 然后在中序序列(In)中查找此根(Pre[0]), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为左子树, 后边的序列为右子树. 设根前边有left个元素.. 则又有, 在前序序列中, 紧跟着根(roo

二叉树的构造和遍历——递归实现

一.二叉树的定义: 二叉树是每个结点最多有两个子树的有序树.二叉树常被用于实现二叉查找树.值得注意的是,二叉树不是树的特殊情形.在图论中,二叉树是一个连通的无环图,并且每一个顶点的度不大于2.有根二叉树还要满足根结点的度不大于2.有了根结点后,每个顶点定义了唯一的根结点,和最多2个子结点.然而,没有足够的信息来区分左结点和右结点. 二.二叉树与树的区别: 二叉树不是树的一种特殊情形,尽管其与树有许多相似之处,但树和二 叉树有两个主要差别: 1. 树中结点的最大度数没有限制,而二叉树结点的最大度数

二叉树构造、遍历和释放--自己写数据结构

直接上代码 bitree.h文件如下: #ifndef _BITREE_H_ #define _BITREE_H_ typedef char TElemType; typedef struct _BitNode { TElemType data; struct _BitNode *lchild,*rchild; }BitNode,*pBitNode; int bittree_creat(BitNode **T); void pre_order(BitNode *T); void mid_orde

二叉树的构造与遍历

1 #include <iostream> 2 using namespace std; 3 4 typedef struct node 5 { 6 char data; 7 struct node *lchild; 8 struct node *rchild; 9 }BiTreeNode,*BiTree; 10 11 void createBiTree(BiTree &T) 12 { 13 char c; 14 cin>>c; 15 if(c=='#') T=NULL;

Java:根据前序遍历与中序遍历构造出一个二叉树

给你前序遍历中序遍历,如何构造出一个二叉树? 思路: 1. 明确前序遍历与中序遍历的顺序 前序遍历:根→左子树→右子树 中序遍历:左子树→根→右子树 2. 根据前序遍历可确认根节点,在中序遍历中根节点是一个分水岭,可由根节点分辨出左右子树 3. 对左右子树分别重复第2步,可以找出左右子树的子树,也就是递归操作 代码: public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x;