您的位置:首页 > 理论基础 > 数据结构算法

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

2016-06-13 00:00 387 查看

一、题目

请写出一个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] =
3ff0
{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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: