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

来源:互联网 发布:盘搜搜源码 编辑:程序博客网 时间:2024/05/17 03:06
  • 题目
    传入一个树的根节点,分别采用非递归实现树的前序,中序,后序遍历。节点定义如下。
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);}
阅读全文
0 0
原创粉丝点击