二叉树的非递归遍历算法

Posted hky8220

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的非递归遍历算法相关的知识,希望对你有一定的参考价值。

技术图片
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct BiNode{//二叉树 
    ElemType data;
    struct BiNode *lchild,*rchlid;
}BiNode,*BiTree;

typedef struct NodeStack{//链栈 
    BiTree data;
    struct NodeStack *next;
}NodeStack;

typedef struct Node{//队列结点
    BiTree data;
    struct Node *next;
}Node;

typedef struct Queue{//链式队列 
    struct Node *front,*rear;
}Queue;

BiTree Create_BiTree(BiTree T);//前序遍历建立二叉树
void PreOrder(BiTree T); //前序遍历
void InOrder(BiTree T);//中序遍历
void PostOrder(BiTree T); //后序遍历
void visit(BiTree T);//访问节点
void InOrder2(BiTree T);//中序遍历非递归算法 
void PreOrder2(BiTree T);//先序遍历非递归算法 
void PostOrder2(BiTree T);//后序遍历非递归算法 
void LevelOrder(BiTree T);//层次遍历 
void InQueue(Queue *q,BiTree t);//入队 
BiTree OutQueue(Queue *q);//出队 
void Push(NodeStack *head,BiTree t);//入栈 
BiTree Pop(NodeStack *head);//出栈 
BiTree GetTop(NodeStack *head);//得到栈顶元素 

int main()
{
    BiTree T;
    T=Create_BiTree(T);
    printf("先序遍历非递归:
");
    PreOrder2(T);
    printf("中序遍历非递归:
");
    InOrder2(T);
    printf("后序遍历非递归:
");
    PostOrder(T);
    printf("层次遍历:
");
    LevelOrder(T);
        
    return 0;
}

BiTree Create_BiTree(BiTree T)
{
    char ch;
    scanf("%c",&ch);
    if(ch==#)
    {
        T=NULL;
     } 
     else
     {
         T=(BiTree)malloc(sizeof(BiNode));
         T->data=ch;
         T->lchild=Create_BiTree(T->lchild);
         T->rchlid=Create_BiTree(T->rchlid);
     }
     return T;
}

void PreOrder(BiTree T)
{
    if(T!=NULL)
    {
        visit(T);
        PreOrder(T->lchild);
        PreOrder(T->rchlid);
    }
}
void InOrder(BiTree T)
{
    if(T!=NULL)
    {
        InOrder(T->lchild);
        visit(T);
        InOrder(T->rchlid);
    }
}
void PostOrder(BiTree T)
{
    if(T!=NULL)
    {
        PostOrder(T->lchild);
        PostOrder(T->rchlid);
        visit(T);
    }
 } 
 
 void visit(BiTree T)
 {
     printf("%c
",T->data);
 }
 
 void InOrder2(BiTree T)
 {
     //InitStack(S)
     NodeStack *s;
    s=(NodeStack*)malloc(sizeof(NodeStack));
    s->next=NULL;

    BiTree p=T;
    while(p||s->next!=NULL)
    {
        if(p)
        {
            Push(s,p);
            p=p->lchild;
        }
        else
        {
            p=Pop(s);
            visit(p);
            p=p->rchlid;
        }
    }    
 }
 
 void PreOrder2(BiTree T)
 {
     //InitStack(S)
     NodeStack *s;
    s=(NodeStack*)malloc(sizeof(NodeStack));
    s->next=NULL;
    
    BiTree p=T;
    while(p||s->next!=NULL)
    {
        if(p)
        {
            visit(p);
            Push(s,p);
            p=p->lchild;
        }
        else
        {
            p=Pop(s);
            p=p->rchlid;
        }
    }    
 }
 
 void PostOrder2(BiTree T)
 {
     NodeStack *s;
    s=(NodeStack*)malloc(sizeof(NodeStack));
    s->next=NULL;
    BiTree p=T,r=NULL;
    while(p||s->next!=NULL)
    {
        if(p)
        {
            Push(s,p);
            p=p->lchild;
        }
        else
        {
            p=GetTop(s);
            if(p->rchlid&&p->rchlid!=r)
            {
                p=p->rchlid;
                Push(s,p);
                p=p->lchild;
            }
            else
            {
                p=Pop(s);
                visit(p);
                r=p;
                p=NULL;
            }
        }
    }
 }
 
 void LevelOrder(BiTree T)
 {
     Queue Q;
     Q.front=Q.rear=(Node*)malloc(sizeof(Node));
    Q.front->next=NULL;
    
    BiTree p;
    InQueue(&Q,T);
    while(Q.front!=Q.rear)
    {
        p=OutQueue(&Q);
        visit(p);
        if(p->lchild!=NULL)
        {
            InQueue(&Q,p->lchild);
        }
        if(p->rchlid!=NULL)
        {
            InQueue(&Q,p->rchlid);
        }
    }
    
 }
 
 void Push(NodeStack *head,BiTree t)
{
    NodeStack *p=(NodeStack*)malloc(sizeof(NodeStack));
    p->data=t;
    p->next=head->next;
    head->next=p;
}

BiTree Pop(NodeStack *head)
{
    NodeStack *p=(NodeStack*)malloc(sizeof(NodeStack));
    p=head->next;
    head->next=p->next;
    return p->data;
}

void InQueue(Queue *q,BiTree t)
{
    Node *p=(Node*)malloc(sizeof(Node));
    p->data=t;
    p->next=NULL;
    q->rear->next=p;
    q->rear=p;
}

BiTree OutQueue(Queue *q)
{
    Node *p=q->front->next;
    q->front->next=p->next;
    if(q->rear==p)
    {
        q->rear=q->front;
    }
    return p->data;
}

BiTree GetTop(NodeStack *head)
{
    return head->next->data;
}
完整代码

一. 中序遍历非递归算法

技术图片

 代码实现:

void InOrder2(BiTree T)
 {
     //InitStack(S)
     NodeStack *s;
    s=(NodeStack*)malloc(sizeof(NodeStack));
    s->next=NULL;

    BiTree p=T;
    while(p||s->next!=NULL)
    {
        if(p)
        {
            Push(s,p);
            p=p->lchild;
        }
        else
        {
            p=Pop(s);
            visit(p);
            p=p->rchlid;
        }
    }    
 }

二. 先序遍历非递归算法

与中序非递归算法相似,只需将访问visit(p)放在入栈Push(p)之前即可。

代码实现:

技术图片
void PreOrder2(BiTree T)
 {
     //InitStack(S)
     NodeStack *s;
    s=(NodeStack*)malloc(sizeof(NodeStack));
    s->next=NULL;
    
    BiTree p=T;
    while(p||s->next!=NULL)
    {
        if(p)
        {
            visit(p);
            Push(s,p);
            p=p->lchild;
        }
        else
        {
            p=Pop(s);
            p=p->rchlid;
        }
    }    
 }
View Code

三. 后序遍历非递归算法

算法思想:

  a.沿着根的左孩子,依次入栈,直到左孩子为空

  b.读栈顶元素:若其右孩子不空且未被访问过,将右子树转执行a,否则,栈顶元素出栈并访问。

代码实现:

void PostOrder2(BiTree T)
 {
     NodeStack *s;
    s=(NodeStack*)malloc(sizeof(NodeStack));
    s->next=NULL;
    BiTree p=T,r=NULL;
    while(p||s->next!=NULL)
    {
        if(p)
        {
            Push(s,p);
            p=p->lchild;
        }
        else
        {
            p=GetTop(s);
            if(p->rchlid&&p->rchlid!=r)
            {
                p=p->rchlid;
                Push(s,p);
                p=p->lchild;
            }
            else
            {
                p=Pop(s);
                visit(p);
                r=p;
                p=NULL;
            }
        }
    }
 }

四. 层次遍历

技术图片

 

 

 代码实现:

void LevelOrder(BiTree T)
 {
     Queue Q;
     Q.front=Q.rear=(Node*)malloc(sizeof(Node));
    Q.front->next=NULL;
    
    BiTree p;
    InQueue(&Q,T);
    while(Q.front!=Q.rear)
    {
        p=OutQueue(&Q);
        visit(p);
        if(p->lchild!=NULL)
        {
            InQueue(&Q,p->lchild);
        }
        if(p->rchlid!=NULL)
        {
            InQueue(&Q,p->rchlid);
        }
    }
    
 }

 

 

运行示例:(按前序遍历建立如下二叉树)

技术图片

 

技术图片

 

以上是关于二叉树的非递归遍历算法的主要内容,如果未能解决你的问题,请参考以下文章

[算法]二叉树的非递归遍历算法

23 遍历二叉树的非递归算法

二叉树的非递归遍历

二叉树的非递归遍历

每日一题如何进行二叉树的各种遍历的非递归算法实现?简要讲述。

每日一题如何进行二叉树的各种遍历的非递归算法实现?简要讲述。