void PreOrderNoRec (BinTree BT)
{ stack S; BinTree p=BT->root;
while ((p != NULL) || !StackEmpty(S))
{ if (p!=NULL)
{ printf (“%c”, p->data); /*访问当前结点*/
Push (S,p); /*将p压入栈S*/
p = p->lchild; } /*将p指向其左子树*/
else
{ p = Top(S);
Pop(S); /*从栈S弹出栈顶元素*/
p = p->rchild; } /*将p指向其右子树*/
}
}
二叉树的非递归遍历中,不是很理解算法里的栈存在的意义是什么,因为最后节点访问顺序的输出是靠printf
在二叉树的非递归遍历算法中,使用栈来辅助遍历的过程。栈的作用主要体现在两个方面:
保存访问过的节点:在遍历二叉树时,需要将已经访问过的节点保存下来,以便在遍历完当前节点的子树后能够回到父节点继续遍历。这时候需要用到一个辅助栈,将已经访问过的节点依次保存到栈中。当遍历完当前节点的子树后,可以从栈中取出上一个访问过的节点,然后继续遍历其右子树。
保存待访问的节点:在遍历二叉树时,需要按照某种次序依次访问树中的节点。在使用递归算法时,系统会自动保存当前的执行状态,因此程序能够在递归返回时正确地继续执行。但是在使用非递归算法时,需要手动保存待访问的节点,以便在遍历完当前节点的左子树后能够继续遍历右子树。这时候也需要用到一个辅助栈,将待访问的节点保存到栈中。
因此,栈在二叉树的非递归遍历算法中扮演了一个重要的角色,它能够帮助我们保存已经访问过的节点,以及待访问的节点,使得程序能够正确地遍历整棵树,并且保证遍历的次序正确。
用栈来代替递归,递归就是先进后出
基于new bing部分指引作答:
在二叉树的非递归遍历算法中,栈的存在有两个主要的意义:
保存节点的访问顺序:栈用于保存待访问的节点,确保按照正确的顺序进行遍历。对于非递归前序遍历、中序遍历和后序遍历,我们需要先访问根节点,然后再访问左子树或右子树。使用栈可以保存未处理的节点,在后续步骤中按照预定的顺序处理这些节点。
回溯到上一层节点:在遍历过程中,当我们完成对当前节点的访问并处理其子节点后,需要回溯到父节点继续遍历其它子节点。使用栈可以方便地记录下一步所需返回的节点,以实现回溯操作。
例如,在非递归中序遍历算法中,我们首先将根节点入栈,然后进入一个循环,将根节点的所有左节点入栈,直到左节点为空。然后从栈中弹出一个节点作为当前节点,并输出其值。接下来,我们将当前节点设为其右子节点,然后重复之前的过程,将右子树的左节点入栈。通过这种方式,我们保持了正确的遍历顺序,并可以回溯到父节点来处理其右子树。
总而言之,栈在非递归遍历中起到了保存节点访问顺序和实现回溯操作的作用,使我们能够以迭代的方式遍历二叉树。
/*9.3编写一个函数print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,
每个记录包括num、name、sore[3],用主函数输入这些记录,用print函数输出这些记录。
编写一个函数input,用来输入5个学生的数据记录。*/
typedef struct{
int num;
char name[20];
int score[3];
}stu;
void printfStu(stu *s,int len){
int i;
stu *p,t;
for(p=s;p<s+len;p++){
t=*p;
printf("学号:%d,姓名:%s,",t.num,t.name);
for(i=0;i<3;i++){
printf("第%d门成绩为%d",i+1,t.score[i]);
}
printf("\n");
}
}
void input1(stu *s,int len){
int i,j;
for(i=0;i<len;i++){
s[i].num=1000+i;
sprintf(s[i].name,"%s_0%d","学生",i);//学生_0i
for(j=0;j<3;j++){
s[i].score[j]=rand()%50+50;
}
}
}
int main(){
stu ss[10];
input1(ss,10);
printfStu(ss,10);
printf("end\n");
return 0;
}