二叉树的遍历(非递归算法)

问题:

假设二叉树节点的定义如下:

struct BTreeNode{
    int val;			// 节点值
    BTreeNode* pLeft;	// 左子树指针
    BTreeNode* pRight;	// 右子树指针
};

请用C++非递归算法分别实现二叉树的先序遍历,中序遍历,后序遍历和层序遍历。


1)先序遍历非递归算法

思路:遍历到某个节点时,如果该节点不为NULL,首先将该节点的值输出,然后将其右孩子节点压栈(如果有的话),然后令该节点指向其左孩子节点;如果当前节点为NULL,而且节点栈非空,则取栈顶节点作为当前节点,并且栈顶节点出栈。代码如下:

void preOrder(BTreeNode* root){
    BTreeNode* pNode = root;
    stack<BTreeNode*> s;

    while (pNode){
        cout << pNode->val << " ";
        if (pNode->pRight)	s.push(pNode->pRight);
        pNode = pNode->pLeft;

        if (!pNode && !s.empty()){
            pNode = s.top();
            s.pop();
        }
    }
    cout << endl;
}


2)中序遍历非递归算法

思路:如果当前节点指针非NULL,则将当前节点指针压栈,并将当前节点指针指向左孩子节点;如果当前节点为NULL,而且栈非空,则输出栈顶节点值,并令当前节点指针指向栈顶节点的右孩子节点,栈顶节点出栈。

void inOrder(BTreeNode* root){
    BTreeNode* pNode = root;
    stack<BTreeNode*> s;
    
    while (pNode || !s.empty()){
        while (pNode){
            s.push(pNode);
            pNode = pNode->pLeft;
        }
        pNode = s.top();
        s.pop();
        
        cout << pNode->val << " ";
        pNode = pNode->pRight;
    }
    cout << endl;
}

3)后序遍历非递归算法

思路:设置一个前驱节点,表示上一次访问的节点,初始为NULL。首先根节点入栈。当栈不为空时,取栈顶节点,判断栈顶节点是否为叶子节点,或者栈顶节点的左孩子或者右孩子刚被访问过,如果是,则栈顶节点出栈并输出;否则分别将栈顶节点右孩子节点入栈(如果非空的话),左孩子节点入栈(如果非空的话)。

void postOrder(BTreeNode* root){
    if (root == NULL)   return;
    
    stack<BTreeNode*> s;
    s.push(root);
    
    BTreeNode* pNode = root;
    BTreeNode* pPre = NULL;
    
    while (!s.empty()){
        pNode = s.top();
        if ((!pNode->pLeft && !pNode->pRight) ||
            (pPre && (pPre == pNode->pLeft || pPre == pNode->pRight))){
            cout << pNode->val << " ";
            pPre = pNode;
            s.pop();
        }
        else{
            if (pNode->pRight)  s.push(pNode->pRight);
            if (pNode->pLeft)   s.push(pNode->pLeft);
        }
    }
    cout << endl;
}

4)层序遍历算法

思路:用一个辅助队列。首先根节点进入队列。当队列不为空时,取队首元素并输出,然后依次将左孩子与右孩子(如果不为空的话)分别插入队列尾。

void levelOrder(BTreeNode* root){
    if (root == NULL)   return;
    
    queue<BTreeNode*> q;
    q.push(root);
    while (!q.empty()){
        BTreeNode* pNode = q.front();
        q.pop();
        cout << pNode->val << " ";
        if (pNode->pLeft)   q.push(pNode->pLeft);
        if (pNode->pRight)  q.push(pNode->pRight);
    }
    cout << endl;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值