二叉树栈的层序遍历

用数组栈实现二叉树的层序遍历

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define  Maxsize   100
  struct tree{
    int data;
    struct tree* left;
    struct tree* right;
};

typedef struct sqstack{
    struct tree* stack[Maxsize];//对应数组中的元素就是指针 
    int front;
    int rear;    
    int coder;
}Sqstack;
Sqstack s;

//初始化栈
 void initstack(Sqstack s)
{        //至于结点数组里面则默认初始化为此对应类型的空指针 
    s.front=0;
    s.rear=0;
    s.coder=0;
 } 
//入栈,此处跟入队列与出队列是差不多的 
void pushstack(struct tree* root)//形参的变量名字不重要,重要的是形参的类型一定要准确,并且要对应 
{
          s.stack[s.front]=root;//s.rear一种保持不变。而s.front每次循环后加一,及指向下一个指针
          s.front=s.front+1; 
    //为什么这里不能传递到postorder函数当中去 
 } 
 
 void instack(struct tree* root)//将二叉树结点按照层次顺序入栈                              //二叉树的根节点就代表了二叉树,擒贼先擒王 
 {
     struct tree* temp2; 
     temp2=root;  //避免改变root,设立一个临时中转指针变量 
     pushstack(temp2);
     while(temp2!=NULL)
     {
         if(temp2->left!=NULL)
         pushstack(temp2->left);//这里调用pushstack的时候已经自动完成了数组栈的累加 
         if(temp2->right!=NULL)
         pushstack(temp2->right);
         temp2= s.stack[++s.rear];//为什么这里会被重复执行呢 ,因为这里的++rear相当于还是重复了头结点的左右结点入栈步骤 
         //这里root的值已经被改变了,不能再由root的值去代表二叉树头结点的值,但是这有什么影响吗? 
     }//这里陷入了死循环 
    
  } 
  
 void postorder()
 {
     
        while(s.front>=1)
        { 
    
       printf("%d ",s.stack[--s.front]->data); 
    }
 }
 


//先暂且不考虑使用这个函数 
struct  tree* popstack()//这里必须要返回一个node类型的指针形成拷贝,便于打印函数调用 
{
    struct tree* temp;
    temp=s.stack[--s.front];
    return temp; 
    
 } 

typedef struct queue{
    struct tree* numQ[Maxsize];//类似int *a[maxsize] 
    int front;
    int rear;
}Queue;

Queue Q;

void initilize()//初始化队列 
{
    Q.front=0; //至于结点数组里面则默认初始化为空指针 
    Q.rear=0;
}

//出队列 
struct tree *pop()
{
    return Q.numQ[++Q.front];
     } 

    
//入队列 
void push(struct tree* root)
{
    Q.numQ[++Q.rear]=root;
}

int empty()
{
    return Q.rear==Q.front;
 } 
 
 
 struct tree*createtree(struct tree* root)
 {
     int x;
     scanf("%d",&x);
     if(x==-1)
     return NULL;
 root=(struct tree*)malloc(sizeof(struct tree));
 root->data=x;
 printf("请输入%d的左子树:",root->data);
 root->left=createtree(root->left);
  printf("请输入%d的右子树:",root->data);
   root->right=createtree(root->right);
  return root;  //最后一层递归返回主函数根节点指针 
 }
 
 
 
 
 void level(struct tree* root)
 {
     struct tree* temp;
     push(root);//首根节点入队列 ,根节点root后续不会发生改变,可再后续传递给其他函数使用 
     while(!empty())
     {              //但是他要返回指向结点类型的指针 
         temp=pop();//pop没有参数,直接依靠直接取指针进行地址上对应变量的直接操作,而非拷贝操作 
         printf("%d ",temp->data); //temp一定要莫二次循环更新时指向刚退出来的那个二叉树结点 
      
     //如何计数每行的结点个数? 
     if(temp->left!=NULL)
        push(temp->left);
      //这里要做标记     
     if(temp->right!=NULL)
       push(temp->right);
   }
 }
 
 //typedef struct sqstack{
//    struct tree* stack[Maxsize];
//    int front;
//    int rear;    
//    int coder;
//}Sqstack;


 
 
 int main()
 {
     Sqstack s;//先声名一个栈的指针地址 
           initstack(s);          //再初始化一个栈 
     printf("请输入头结点:");
     struct tree* root=createtree(root);
     
     
     initilize();//构造二叉树与初始化队列之间是不冲突的,至于结点数组里面则默认初始化为空指针  
     printf("按照正序的层次遍历\n"); 
     level(root);
     putchar('\n');
     printf("按照栈逆序的层次遍历\n");
     instack(root);
 postorder();
     return 0; 
     
      
 }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,二叉树的遍历有三种主要方式:先序遍历(根-左-右)、中序遍历(左-根-右)和后序遍历(左-右-根)。非递归的层次遍历(也叫广度优先遍历,从上到下、从左到右)通常使用队列来辅助实现。 这里分别给出这些遍历的非递归算法代码: 1. 层序遍历(广度优先遍历): ```c #include <stdio.h> #include <stdlib.h> #include <queue> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void levelOrder(struct TreeNode* root) { if (root == NULL) return; // 使用队列存储每一层的节点 queue<struct TreeNode*> q; q.push(root); while (!q.empty()) { int size = q.size(); for (int i = 0; i < size; i++) { struct TreeNode* node = q.front(); q.pop(); printf("%d ", node->val); // 打印当前节点值 if (node->left != NULL) q.push(node->left); if (node->right != NULL) q.push(node->right); } printf("\n"); // 换行表示新的一层 } } ``` 2. 先序遍历(递归和非递归两种方式,这里是非递归版本,使用): ```c void preorderNonRecursive(struct TreeNode* root) { if (root == NULL) return; stack<struct TreeNode*> s; s.push(root); while (!s.empty()) { struct TreeNode* node = s.top(); s.pop(); printf("%d ", node->val); // 打印当前节点值 if (node->right != NULL) s.push(node->right); if (node->left != NULL) s.push(node->left); } } ``` 3. 中序遍历(非递归,同样使用): ```c void inorderNonRecursive(struct TreeNode* root) { if (root == NULL) return; stack<struct TreeNode*> s; struct TreeNode* curr = root; while (curr != NULL || !s.empty()) { while (curr != NULL) { s.push(curr); curr = curr->left; } curr = s.top(); s.pop(); printf("%d ", curr->val); // 打印当前节点值 curr = curr->right; } } ``` 4. 后序遍历(非递归,使用两个): ```c void postorderNonRecursive(struct TreeNode* root) { if (root == NULL) return; stack<struct TreeNode*> s1, s2; s1.push(root); while (!s1.empty()) { struct TreeNode* node = s1.top(); s1.pop(); s2.push(node); if (node->left != NULL) s1.push(node->left); if (node->right != NULL) s1.push(node->right); } while (!s2.empty()) { struct TreeNode* node = s2.top(); s2.pop(); printf("%d ", node->val); // 打印当前节点值 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值