现在的位置: 首页 > 综合 > 正文

算法导论 10.4-2 O(n)时间 递归遍历二叉树

2019年03月07日 ⁄ 综合 ⁄ 共 5023字 ⁄ 字号 评论关闭

一、题目

请写出一个O(n)时间的递归过程,在给定的n个结点的二叉树后,它可以将树中每个结点的关键字输出来

 

二、伪代码

01.TREE-PRINT(T)  
02.1    print key[T]  
03.2    if left[T] != NIL  
04.3        TREE-PRINT(left[T])  
05.4    if right[T] != NIL  
06.5        TREE-PRINT(right[T])  

 

三、代码

1.main.cpp

#include "caselib.h"

int main()
{
	CTestFrame test;
	//test.inputNullWillShowErrorHint();
	test.oneNoteWillSecuss();
	test.rootWithLeftChildWillSecuss();
	test.rootWithRightChildWillSecuss();
	test.treeWithGraph10_4_1WillSecuss();
	test.onlyLeftChildWillSecuss();
	getchar();
	return 0;
}

 

2.caselib.h

#include <vector>
#include <string>
using namespace std;

class CTestFrame
{
	typedef bool (CTestFrame::*pFunc)();

	vector<int> outputDataVec;
	vector<int> inputDataVec;
	vector<int> expectOutputDataVec;

	void prepare(int* inputData, int *expectOutputData, int inLen, int outLen);
	bool testStep();
	void backup();
	void assertTrue(CTestFrame::pFunc testedFunc, string errorPrint);
public:
	void inputNullWillShowErrorHint();
	void oneNoteWillSecuss();
	void rootWithLeftChildWillSecuss();
	void rootWithRightChildWillSecuss();
	void treeWithGraph10_4_1WillSecuss();
	void onlyLeftChildWillSecuss();
};

3.caselib.cpp

#include "funclib.h"
#include "caselib.h"

void CTestFrame::prepare(int* inputData, int *expectOutputData, int inLen, int outLen)
{
	int dataNum = 0;
	for(int i = 0; i < inLen; i++)
	{
		inputDataVec.push_back(inputData[i]);
		if(inputData[i] != NONODE)
			dataNum++;
	}
	//assert(dataNum == outLen)
	for(int i = 0; i < outLen; i++)
		expectOutputDataVec.push_back(expectOutputData[i]);
}

bool CTestFrame::testStep()
{
	bool ret = false;
	biTree *pBiTree = new biTree(inputDataVec);
	outputDataVec = pBiTree->recursiveTraversal();
	delete pBiTree;

	if(outputDataVec.size() != expectOutputDataVec.size())
		ret = false;
	else
	{
		ret = true;
		for(int i =0; i < outputDataVec.size(); i++)
		{
			if(outputDataVec[i] != expectOutputDataVec[i])
			{
				ret = false;
				break;
			}
		}
	}
	return ret;
}

void CTestFrame::backup()
{
	inputDataVec.clear();
	outputDataVec.clear();
	expectOutputDataVec.clear();
}

void CTestFrame::assertTrue(CTestFrame::pFunc testedFunc, string errorPrint)
{
	if((this->*testedFunc)() != true)
	{
		cout<<"failed: "<<errorPrint<<endl;
	}
}

void CTestFrame::oneNoteWillSecuss()
{
	int inputData[1] = {5};
	int expectOutputData[1] = {5};
	prepare(inputData, expectOutputData, 1, 1);
	assertTrue(&CTestFrame::testStep, "The result is not correct when the bi-tree contains only one note");
	backup();
}

void CTestFrame::rootWithLeftChildWillSecuss()
{
	int inputData[2] = {5,
					10};
	int expectOutputData[2] = {5, 10};
	prepare(inputData, expectOutputData, 2, 2);
	assertTrue(&CTestFrame::testStep, "A root with a left node will not secuss");
	backup();
}

void CTestFrame::rootWithRightChildWillSecuss()
{
	int inputData[3] = {5, 
				NONODE, 10};
	int expectOutputData[2] = {5, 10};
	prepare(inputData, expectOutputData, 3, 2);
	assertTrue(&CTestFrame::testStep, "A root with a right node will not secuss");
	backup();
}

void CTestFrame::treeWithGraph10_4_1WillSecuss()
{
	int inputData[10] = {18,
				12,         	 10,
			7,         4,     2,      21,
     NONODE, NONODE, 5};
	int expectOutputData[8] = {18, 12, 7, 4, 5, 10, 2, 21};
	prepare(inputData, expectOutputData, 10, 8);
	assertTrue(&CTestFrame::testStep, "test case with graph in Exercise 10.4_1 will fail");
	backup();
}

void CTestFrame::onlyLeftChildWillSecuss()
{
	int inputData[8] = {1,
				2,         	 NONODE,
			3,    NONODE,  NONODE,      NONODE,
		4};
	int expectOutputData[4] = {1, 2, 3, 4};
	prepare(inputData, expectOutputData, 8, 4);
	assertTrue(&CTestFrame::testStep, "only left child will false");
	backup();
}

4.funclib.h

#include <iostream>
#include <vector>
using namespace std;

#define NONODE -0x7FFFFFF

struct biTreeNode
{
	int key;
	biTreeNode *pLeftChild;
	biTreeNode *pRightChild;
	biTreeNode *pParent;
	biTreeNode(){}
	~biTreeNode();
	biTreeNode(int x):key(x),pLeftChild(NULL),pRightChild(NULL){}

	void biTreeNode::recursiveVisit(vector<int> *pDataVec);
};

//二叉树
class biTree
{
	biTreeNode *pRootNode;
public:
	biTree(const vector<int> nodeKeyVec);
	~biTree();

	vector<int> recursiveTraversal();
};

5.funclib.cpp

#include "funclib.h"
#include <queue>

#define LEFT 0
#define RIGHT 1

void addNodeToChild(biTreeNode* pCurrentNode, biTreeNode* pChild, bool leftOrRight);

biTreeNode::~biTreeNode()
{
	if(pLeftChild != NULL)
		delete pLeftChild;
	if(pRightChild != NULL)
		delete pRightChild;
}

void biTreeNode::recursiveVisit(vector<int> *pDataVec)
{
	pDataVec->push_back(key);

	if(pLeftChild != NULL)
		pLeftChild->recursiveVisit(pDataVec);
	if(pRightChild)
		pRightChild->recursiveVisit(pDataVec);
}

biTree::~biTree()
{
	if(pRootNode != NULL)
		delete pRootNode;
}

biTree::biTree(const vector<int> nodeKeyVec)
{
	pRootNode = new biTreeNode(nodeKeyVec[0]);
	queue<biTreeNode*> nodeQueue;
	nodeQueue.push(pRootNode);
	for(int i = 1; i < nodeKeyVec.size(); i = i+2)
	{
		biTreeNode *pCurrentNode = nodeQueue.front();
		nodeQueue.pop();
		if(pCurrentNode != NULL && i < nodeKeyVec.size() && nodeKeyVec[i] != NONODE)
		{
			biTreeNode* pLeftChild = new biTreeNode(nodeKeyVec[i]);
			addNodeToChild(pCurrentNode, pLeftChild, LEFT);
			nodeQueue.push(pLeftChild);
		}
		else
			nodeQueue.push(NULL);
		if(pCurrentNode != NULL && i+1 < nodeKeyVec.size() && nodeKeyVec[i+1] != NONODE)
		{
			biTreeNode* pRightChild = new biTreeNode(nodeKeyVec[i+1]);
			addNodeToChild(pCurrentNode, pRightChild, RIGHT);
			nodeQueue.push(pRightChild);
		}
		else
			nodeQueue.push(NULL);
	}
}

vector<int> biTree::recursiveTraversal()
{
	vector<int> retVec;
	if(pRootNode != NULL)
		pRootNode->recursiveVisit(&retVec);
	return retVec;
}

void addNodeToChild(biTreeNode* pCurrentNode, biTreeNode* pChild, bool leftOrRight)
{
	if(leftOrRight == LEFT)
		 pCurrentNode->pLeftChild = pChild;
	else
		pCurrentNode->pRightChild = pChild;
	pChild->pParent = pCurrentNode;
}

抱歉!评论已关闭.