用数组栈实现二叉树的层序遍历
#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;
}