您的位置:首页 > 职场人生

程序员面试金典: 9.4树与图 4.4 在二叉树上创建包含某一深度上所有节点的链表

2016-12-29 10:04 591 查看
#include <iostream>
#include <stdio.h>
#include <string>
#include <queue>
#include <vector>

using namespace std;

/*
问题:给定一颗二叉树,设计一个算法,创建含有某一深度上所有节点的链表(比如,若一棵树的深度为D,
则会创建出D个链表)。
分析:题目的意思应该是深度为1的所有节点构成一个链表,深度为2的所有节点构成一个链表,....,也就是把
相同深度的节点放在同一个链表中。
那么肯定要遍历,我们知道层次遍历最好的方式应该是用广度优先。可以事先创建D个链表,
每当遍历到一个节点,获取该节点深度,将该节点放入到对应深度的链表中,结点插入链表的方式可以采用
尾插法。
当所有结点遍历结束,此时D个链表也已经建立好。
而树的深度D,可以通过一个递归实现。

输入:
6(树中结点个数n)
1 2 3 4 5 6(树中结点的值,接下来有n行,每i行第一个字符:'d'表示第i个结点有两个孩子,随后给出两个孩子节点编号,
'l'表示第i个结点只有左孩子,然后给出左孩子结点编号;'r'表示第i个结点只有右孩子,给出右孩子节点编号,'z'表示第i个结点没有孩子结点)
d 2 3
d 4 5
r 6
z
z
z
输出:
depth 1: 1 ,depth 2: 2 3, depth 3: 4 5 6
*/
const int MAXSIZE = 10000;

typedef struct TreeNode
{
int _value;
TreeNode* _pLeft;
TreeNode* _pRight;
bool _isVisited;
int _height;
//TreeNode* _pParent;
}TreeNode;
int g_index;
TreeNode g_treeNodeArray[MAXSIZE];

typedef struct Node
{
Node* _pNext;
int _value;
}Node;

TreeNode* createTreeNode()
{
++g_index;
g_treeNodeArray[g_index]._pLeft = g_treeNodeArray[g_index]._pRight = NULL;
g_treeNodeArray[g_index]._isVisited = false;
return &g_treeNodeArray[g_index];
}

vector< Node* > visitTreeBFS(TreeNode* head)
{
vector<Node*> vecNode;
if(NULL == head)
{
return vecNode;
}
queue<TreeNode*> queueTree;
head->_height = 0;//设置根结点的高度为1
queueTree.push(head);
vector<Node*> tailNodeVector; //用于存放对应链表的尾结点
while(!queueTree.empty())
{
TreeNode* treeNode = queueTree.front();
queueTree.pop();
int height = treeNode->_height;

//将当前节点加入到与其深度相统一的链表中,说明深度为height对应的链表还没有建立
if(vecNode.empty() || height == vecNode.size() )
{
//建立链表,尾插法,创建尾结点,创建一个新节点,令尾结点为新结点;后续再插结点时,令尾结点指向新结点,再令尾结点为新结点
Node* pNode = new Node();
pNode->_value = treeNode->_value;
pNode->_pNext = NULL;
vecNode.push_back(pNode);
tailNodeVector.push_back(pNode);
}
else
{
Node* pNode = new Node();
pNode->_value = treeNode->_value;
pNode->_pNext = NULL;
Node* tailNode = tailNodeVector.at(height);
tailNode->_pNext = pNode;
tailNode = pNode;
tailNodeVector.at(height) = tailNode; //更新尾结点
}

//左子树非空且未访问过,则压入左子树
if(treeNode->_pLeft && treeNode->_pLeft->_isVisited == false)
{
treeNode->_pLeft->_isVisited = true;
treeNode->_pLeft->_height = height + 1;
queueTree.push(treeNode->_pLeft);
}
if(treeNode->_pRight && treeNode->_pRight->_isVisited == false)
{
treeNode->_pRight->_isVisited = true;
treeNode->_pRight->_height = height + 1;
queueTree.push(treeNode->_pRight);
}
}

return vecNode;
}

void printResult(vector<Node*>& vecNode)
{
if(vecNode.empty())
{
cout << "List is null!" << endl;
}
int size = vecNode.size();
for(int i = 0 ; i < size ; i++)
{
cout << "depth " << (i+1) << ":";
Node* node = vecNode.at(i);
while(node)
{
cout << node->_value << " ";
node = node->_pNext;
}
cout << ",";
}
cout << endl;
}

void releaseList(vector<Node*>& vecNode)
{
if(vecNode.empty())
{
return;
}
int size = vecNode.size();
for(int i = 0 ; i < size ; i++)
{
Node* node = vecNode.at(i);
//删除节点
while(node)
{
Node* tempNode = node;
node = node->_pNext;
delete tempNode;
}
}
}

void input()
{
int nodeNum;
int nodeValue;
string childNumFlag;
int leftChild;
int rightChild;
while(cin >> nodeNum)
{
g_index = 0;
for(int i = 0 ; i < nodeNum ; i++)
{
TreeNode* treeNode = createTreeNode();
cin >> treeNode->_value;
}

//接下来创建结点指向
for(int i = 1 ; i <= nodeNum ; i++)
{
cin >> childNumFlag;
if("d" == childNumFlag)
{
cin >> leftChild >> rightChild;
g_treeNodeArray[i]._pLeft = &g_treeNodeArray[leftChild];
g_treeNodeArray[i]._pRight = &g_treeNodeArray[rightChild];
}
else if("r" == childNumFlag)
{
cin >> rightChild;
g_treeNodeArray[i]._pRight = &g_treeNodeArray[rightChild];
}
else if("l" == childNumFlag)
{
cin >> leftChild;
g_treeNodeArray[i]._pLeft = &g_treeNodeArray[leftChild];
}
}

//下面就是遍历树,创建链表
vector< Node* > vecNode = visitTreeBFS(&g_treeNodeArray[1]);

//遍历后打印结果
printResult(vecNode);
releaseList(vecNode);
}
}

int main(int argc , char* argv[])
{
input();
getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐