如何用一个栈实现二叉树的螺旋遍历

本文介绍如何利用单个栈实现二叉树的螺旋遍历,结合二叉树基本遍历方法和树的高度求解技巧,通过构建二叉树属性并修改遍历函数,最终实现螺旋遍历效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       相信大家用两个栈(两个栈可以实现一个队列的效果)来实现二叉树的螺旋遍历是一件比较容易(写起来也不是十分轻松)的活吧,但是如果用一个栈就能实现这个问题的话,看来我们得花点心思了!!(嘻嘻) 

      那么什么是螺旋遍历呢?

---------------1-----------------
--------3-----------2---------------
---4------5-----6-------7
-----------------------------8

螺旋遍历的结果是:12345678

        我们要借助前两章讲解的一些基础知识混合在一起我们才能解决这个问题,以下是我们从前几篇的博客中得到的基本信息,希望大家理解

       1.二叉树基本三种遍历(前序中序后序)都可以用一个栈来实现非递归遍历(这篇博客小生写过哦,如果不懂可以看看的)

       2.不管三种遍历的哪种遍历,对于同层元素都是左边元素右边元素的前面(前序:中左右,中序:左中右,后序:左右中)

      3.树的高度可以辨识中一颗树种哪些元素是在同一层的(关于树中任意元素的高度求法可以参见我的博客)

 通过以上三点我们就可以实现对二叉树的螺旋遍历的吗?(基本上可以吧,但是需要进行两项改造)

首先获取树节点的高度

int get_depth(BinaryTreeNode *r)  
{  
    int depth=0;  
    if(r)  
    {  
        int a=get_depth(r->m_pleft);  
        int b=get_depth(r->m_pright);  
        depth=(a>b)?a:b;  
        depth++;  
    }  
    return depth;  
}  

        其实我们在构建二叉树的属性时候就可以把高度这个值付给二叉树作为树的基本属性,这样我们建树的时候就就可以赋值高度这个值(关键在于你的爱好)

我们再改写一下树的先序遍历让它只打印同层指定的节点

void preOrder2Left(BinTree *root,int height)     //非递归前序遍历 
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {

          if(p->height==height)   cout<<p->data<<" ";

            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            s.pop();
            p=p->rchild;
        }
    }
}

         上面的先序遍历我们只能打印从左到右同层元素,要是打印从右到左同层元素我们还要再改写一次,只是将遍历顺序变了一下即变成”右左中“的伪先序遍历我们称为preOrder2Right(BinTree *root,int height),放的元素和先序一样只是顺序相反而已(先放右在放左了),相信你一定可以写出来的

于是我们的主函数就可以这样写了

int main(){

    BinaryTreeNode *r;

    int depth = getDepth(r);

          for(int i=0;i<depth;i++){

                  if(i%2) preOrder2Right(r,i);

                  else   preOrder2Left(r,i);

    }

}

不知道你们有什么收获,我们共同进步

二叉树螺旋线序遍历(也称为之字形遍历)是一种特殊的遍历方式,它按照层级进行遍历,但每一层的遍历方向交替变化。以下是一个不使用的C++实现方法: ```cpp #include <iostream> #include <vector> #include <queue> #include <deque> using namespace std; struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; vector<vector<int>> zigzagLevelOrder(TreeNode* root) { vector<vector<int>> result; if (!root) return result; queue<TreeNode*> q; q.push(root); bool leftToRight = true; while (!q.empty()) { int size = q.size(); deque<int> level; for (int i = 0; i < size; ++i) { TreeNode* node = q.front(); q.pop(); if (leftToRight) { level.push_back(node->val); } else { level.push_front(node->val); } if (node->left) q.push(node->left); if (node->right) q.push(node->right); } result.push_back(vector<int>(level.begin(), level.end())); leftToRight = !leftToRight; } return result; } int main() { // 构建一个示例二叉树 TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); root->left->left = new TreeNode(4); root->left->right = new TreeNode(5); root->right->left = new TreeNode(6); root->right->right = new TreeNode(7); // 进行螺旋线序遍历 vector<vector<int>> result = zigzagLevelOrder(root); // 输出结果 for (const auto& level : result) { for (int val : level) { cout << val << " "; } cout << endl; } return 0; } ``` 这个实现使用了队列来进行层级遍历,并且使用双端队列(deque)来存储每一层的节点值。通过一个布尔变量`leftToRight`来控制每一层的遍历方向。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值