第五章 二叉树非递归遍历
先序遍历 先遍历根节点其次左子树和右子树 中序遍历 先遍历左子树其次根节点最后右子树 后序遍历 先左子树再右子树最后根节点
还是上个博客的图 先序遍历结果 1 2 4 6 3 5 (根左右) 1是根 2 4 6 是左子树 3 5 是右子树 中序遍历结果 2 6 4 1 3 5 (左根右) 2 6 4 是左子树 1 是根 3 5 是右子树 后序遍历结果 6 4 2 5 3 1 (左右根) 6 4 2 是左子树 5 3 是右子树 1 是根 今天用栈来实现非递归遍历 非递归VS递归 递归一般比较好像容易实现 但是占用空间资源比较多,递归的层次越多,资源占用越大。
非递归就比较难实现,同时还要依托栈来实现。但空间利用高一点。运行时间也会相较递归短很多。
先序遍历 根左右 先访问根节点,同时压栈。纵深左子树(先访问后压栈),当左子树空了,退栈纵深右子树(先访问后压栈)。直至没有节点同时栈空。
void PreOrder2(BiTree T){
Stack S=(Stack)malloc(sizeof(struct stack));
Initstack(S);
BiTree p=T;
while(p||!isEmpty(S)){
if(p){
printf("%c ",p->data);
push(S,p);
p=p->lchild;
}
else{
pop(S,p);
p=p->rchild;
}
}
free(S);
}
中序遍历 左根右 第一步,纵深左子树,同时压栈。直至左孩子为空了,说明这是可以访问的节点了。 第二步,退栈并访问,检查是否有右孩子。若右孩子为空,继续执行第二步。若存在右孩子,转向右子树执行第一步。
void InOrder2(BiTree T){
Stack S=(Stack)malloc(sizeof(struct stack));
Initstack(S);
BiTree p=T;
while(p||!isEmpty(S)){
if(p){
push(S,p);
p=p->lchild;
}
else{
pop(S,p);
printf("%c ",p->data);
p=p->rchild;
}
}
free(S);
}
后序遍历 左右根 第一步,沿着根的左孩子依次入栈,直至左孩子为空。 第二步,读栈顶元素,若其右孩子不空且被未被访问过,转向右子树执行第一步。否则,出栈并访问。
void PostOrder2(BiTree T){
Stack S=(Stack)malloc(sizeof(struct stack));
Initstack(S);
BiTree p=T;
BiTree r=NULL;
while(p||!isEmpty(S)){
if(p){
push(S,p);
p=p->lchild;
}
else{
GetTop(S,p);
if(p->rchild&&p->rchild!=r)
p=p->rchild;
else{
pop(S,p);
printf("%c ",p->data);
r=p;
p=NULL;
}
}
}
free(S);
}
贴一下完整的代码 包含了栈的定义,出入栈,访问栈顶元素等。 使用了带头结点的链栈。出栈入栈容易实现和理解!之前的稿子也写了几次栈了,这里的代码就不详细注释了。
#include<stdio.h>
#include<stdlib.h>
typedef struct BiNode{
char data;
struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct stack{
BiTree data;
struct stack *next;
}stack,*Stack;
bool Initstack(Stack &S){
S->next=NULL;
return true;
}
bool push(Stack &S,BiTree p){
Stack q=(Stack)malloc(sizeof(struct stack));
q->data=p;
q->next=S->next;
S->next=q;
return true;
}
bool pop(Stack &S,BiTree &p){
if(S->next==NULL) return false;
Stack q=S->next;
S->next=q->next;
p=q->data;
free(q);
return true;
}
bool GetTop(Stack &S,BiTree &p){
if(S->next==NULL) return false;
Stack q=S->next;
p=q->data;
return true;
}
bool isEmpty(Stack S){
if(S->next==NULL) return true;
else return false;
}
void CreateTree(BiTree &T){
char ch;
scanf("%c\n",&ch);
if(ch=='#')
T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiNode));
T->data=ch;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}
void PreOrder(BiTree T){
if(T!=NULL){
if(T->data!='#')
printf("%c ",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void PreOrder2(BiTree T){
Stack S=(Stack)malloc(sizeof(struct stack));
Initstack(S);
BiTree p=T;
while(p||!isEmpty(S)){
if(p){
printf("%c ",p->data);
push(S,p);
p=p->lchild;
}
else{
pop(S,p);
p=p->rchild;
}
}
free(S);
}
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild);
if(T->data!='#')
printf("%c ",T->data);
InOrder(T->rchild);
}
}
void InOrder2(BiTree T){
Stack S=(Stack)malloc(sizeof(struct stack));
Initstack(S);
BiTree p=T;
while(p||!isEmpty(S)){
if(p){
push(S,p);
p=p->lchild;
}
else{
pop(S,p);
printf("%c ",p->data);
p=p->rchild;
}
}
free(S);
}
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
if(T->data!='#')
printf("%c ",T->data);
}
}
void PostOrder2(BiTree T){
Stack S=(Stack)malloc(sizeof(struct stack));
Initstack(S);
BiTree p=T;
BiTree r=NULL;
while(p||!isEmpty(S)){
if(p){
push(S,p);
p=p->lchild;
}
else{
GetTop(S,p);
if(p->rchild&&p->rchild!=r)
p=p->rchild;
else{
pop(S,p);
printf("%c ",p->data);
r=p;
p=NULL;
}
}
}
free(S);
}
int main(){
BiTree T;
CreateTree(T);
printf("先序遍历: ");
PreOrder(T);
printf("\n中序遍历: ");
InOrder(T);
printf("\n后序遍历: ");
PostOrder(T);
printf("\n非递归先序遍历:");
PreOrder2(T);
printf("\n非递归中序遍历:");
InOrder2(T);
printf("\n非递归后序遍历:");
PostOrder2(T);
return 0;
}
结果展示
|