1. 程式人生 > >完整類實現:構造,析構,遍歷二叉樹

完整類實現:構造,析構,遍歷二叉樹

根據前面一個博文內容已經講述瞭如何根據兩種遍歷方式進行構建二叉樹

這裡利用遞迴方式遍歷二叉樹,遞迴方式比較簡單,後續補充其餘非遞迴方式

再此主要是完善類的使用:
其中重點在於:介面定義

二叉樹的析構刪除

以及類成員變數中如果有指標,同時涉及複製建構函式和賦值操作符函式時需要用到的智慧指標

如果介面方面定義不夠好,還望包涵

如果有對智慧指標不理解的地方,可以移步 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>