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

剑指offer面试题-二叉树的前序中序后序遍历

2017-07-26 20:45 204 查看
题目

传入一个树的根节点,分别采用非递归实现树的前序,中序,后序遍历。节点定义如下。

struct BinaryTreeNode
{
BinaryTreeNode(char data)
:_pLeftChild(NULL)
, _pRightChild(NULL)
, _data(data)
{}
BinaryTreeNode *_pLeftChild;
BinaryTreeNode *_pRightChild;
char _data;
};


创建树的代码

void _CreateBinaryTree(BinaryTreeNode *&pRoot, char *pStr, size_t size, size_t& index)
{//此处index一定要用引用
if (index < size && '#' != pStr[index])
{
pRoot = new  BinaryTreeNode(pStr[index]);
_CreateBinaryTree(pRoot->_pLeftChild, pStr, size, ++index);
_CreateBinaryTree(pRoot->_pRightChild, pStr, size, ++index);
}
}


前序遍历

实现思路

采用栈实现,首先将根入栈

栈不为空循环

取栈顶元素访问,出栈

右孩子不为空右孩子入栈

左孩子不为空左孩子入栈

实现代码

void PreOrder(BinaryTreeNode *pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTreeNode *> s;
s.push(pRoot);
while (!s.empty())
{
BinaryTreeNode *top = s.top();
cout << top->_data;
s.pop();
if (top->_pRightChild)
s.push(top->_pRightChild);
if (top->_pLeftChild)
s.push(top->_pLeftChild);
}
}


测试用例:

void testpre()
{
BinaryTreeNode *pRoot;
char *str = "abcd"; // 左单支
size_t size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
PreOrder(pRoot);
cout << endl;
str = "a#b#c#d";//右单支
size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
PreOrder(pRoot);
cout << endl;
str = "ab#df##g##ce#h";//普通树
size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
PreOrder(pRoot);
PreOrder(NULL);
}


中序遍历

实现思路

定义一个结点从根开始寻找最左边的结点

栈不为空,且结点不为空循环

寻找最左边节点,并将沿途结点入栈

访问栈顶元素,出栈

如果有右孩子,将右孩子赋给定义 的结点。

实现代码

void Inorder(BinaryTreeNode *pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTreeNode *> s;
BinaryTreeNode *pCur = pRoot;
while (!s.empty() || pCur)
{
while (pCur)
{
s.push(pCur);
pCur = pCur->_pLeftChild;//寻找最左边的结点
}
BinaryTreeNode *top = s.top();
cout << top->_data;
s.pop();
pCur = top->_pRightChild;
}
}


测试用例

void testin()
{
BinaryTreeNode *pRoot;
char *str = "abcd"; // 左单支//dcba
size_t size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
Inorder(pRoot);
cout << endl;
str = "a#b#c#d";//右单支//abcd
size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
Inorder(pRoot);
cout << endl;
str = "ab#df##g##ce#h";//普通树//bfdgaehc
size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
Inorder(pRoot);
Inorder(NULL);
}


后序遍历

实现思路

定义一个结点pCur寻找最左边的结点,定义一个pPre保存前一个访问节点。

栈不为空或者pCur不为空循环

寻找 最左边的结点,并将沿途结点入栈

如果栈顶元素没有右孩子,或者右孩子刚刚被访问过,访问栈顶元素,并弹出

有右孩子将右孩子赋值给pCur循环继续

void postorder(BinaryTreeNode *pRoot)
{
if (NULL == pRoot)
return;
stack<BinaryTreeNode *> s;
BinaryTreeNode *pCur = pRoot;
BinaryTreeNode *pPre = NULL;
while (!s.empty() || pCur)
{
while (pCur)
{
s.push(pCur);
pCur = pCur->_pLeftChild;
}
BinaryTreeNode *top = s.top();
if (NULL == top->_pRightChild || pPre == top->_pRightChild)
{
cout << top->_data << " ";
pPre = top;
s.pop();
}
else
pCur = top->_pRightChild;
}
}


测试用例

void testpost()
{
BinaryTreeNode *pRoot;
char *str = "abcd"; // 左单支//dcba
size_t size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
postorder(pRoot);
cout << endl;
str = "a#b#c#d";//右单支//dcba
size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
postorder(pRoot);
cout << endl;
str = "ab#df##g##ce#h";//普通树//
size = 0;
_CreateBinaryTree(pRoot, str, strlen(str), size);
postorder(pRoot);
postorder(NULL);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: