二叉树递归层次遍历和前中后序遍历


//!!!关于涉及到指针的一定一定要注意!!!
//因为有时候会是多重指针 指针 指针的指针 因为都是指针类型 所以编译时候不会报错 但肯定有问题 指针本身是地址 地址发生了变化 自然而然有所差错
//最好的办法就是队和栈按照原来的代码写 用typedef BiTree QElemType/SElemType定义一下 可以避免差错
//当然最重要的一点是搞清楚队和栈的元素到底是什么 应该是BiTree而不是BiTNode 因为后面会涉及到lchild和rchild
//按照先序遍历方法来建立二叉树的 所以在输入的时候需要注意 把二叉树按照先序遍历 如果没有某子节点 也要输入进去
//加油!!!
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;

//Tree
typedef char ElemType;
typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;
void InitBiTree(BiTree *T)
{
    *T=NULL;
}
void CreateBiTree(BiTree *T)  //按照先序遍历顺序创建的二叉树
{
    char ch;

    scanf("%c",&ch);

        if(ch!='\n')
        {

         if(ch=='^')
         {
             (*T)=NULL;
         }
         else
        {
            (*T)=(BiTree)malloc(sizeof(BiTNode));
            if(!(*T)) exit(OVERFLOW);

            (*T)->data=ch;

            CreateBiTree(&(*T)->lchild);
            CreateBiTree(&(*T)->rchild);
        }

        }

}
int BiTreeDepth(BiTree T)
{
   int LD,RD;

    if(T==NULL)
        return 0;
    else
    {
        LD=BiTreeDepth(T->lchild);
        RD=BiTreeDepth(T->rchild);

        return LD>RD?LD+1:RD+1;
    }

}
void Print(BiTree T)
{
    int row,col;
    int m,r,l,i,j;
    BiTNode a[100][100]={};

    if(T)
    {
    row=BiTreeDepth(T);
    col=pow(2,row)-1;

    for(i=1;i<=row-1;i++)
    {
        for(j=1;j<=pow(2,i-1);j++)
        {
            m=(2*j-1)*pow(2,row-i);
            l=(4*j-3)*pow(2,row-i-1);
            r=(4*j-1)*pow(2,row-i-1);

            if(i==1)
                a[i][m]=*T;

            if(a[i][m].lchild)
                a[i+1][l]=*(a[i][m].lchild);

            if(a[i][m].rchild)
                a[i+1][r]=*(a[i][m].rchild);
        }
    }

    for(i=1;i<=row;i++)
    {
        for(j=1;j<=col;j++)
        {
            if(a[i][j].data)
                printf("%c",a[i][j].data);
            else printf(" ");
        }
        printf("\n");
    }
}
}

//Stack
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct Stack
{
    BiTree *base;
    BiTree *top;
    int stacksize;
}Stack;

Status InitStack(Stack *S)
{
    (*S).base=(BiTree *)malloc(STACK_INIT_SIZE*sizeof(BiTree));
    if(!(*S).base) exit(OVERFLOW);
    (*S).top=(*S).base;
    (*S).stacksize=STACK_INIT_SIZE;
    return OK;
}
Status StackEmpty(Stack S)
{
    return S.top==S.base?TRUE:FALSE;
}
Status GetTop(Stack S,BiTree *p)
{
    if(StackEmpty(S))
        return ERROR;

    *p=*(S.top-1);
    return OK;
}
Status Push(Stack *S,BiTree e)
{
    if((*S).top-(*S).base>=(*S).stacksize)
    {
        (*S).base=(BiTree *)realloc((*S).base,(STACKINCREMENT+STACK_INIT_SIZE)*sizeof(BiTree));
        if(!(*S).base) exit(OVERFLOW);
        (*S).top=(*S).base+(*S).stacksize;
        (*S).stacksize+=STACKINCREMENT;
    }
    *((*S).top++)=e;
    return OK;
}
Status Pop(Stack *S,BiTree *p)
{
    if(StackEmpty(*S))
        return ERROR;

    *p=*(--(*S).top);
    return OK;
}

//Queue
typedef struct QNode
{
    BiTree data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue *Q)
{
    (*Q).front=(QueuePtr)malloc(sizeof(QNode));
    if(!(*Q).front) exit(OVERFLOW);
    (*Q).rear=(*Q).front;
    (*Q).front->next=NULL;
    return OK;
}
Status QueueEmpty(LinkQueue Q)
{
    return Q.front==Q.rear?TRUE:FALSE;
}
Status EnQueue(LinkQueue *Q,BiTree e)
{
    QueuePtr p;

    p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);

    p->next=NULL;
    p->data=e;

    (*Q).rear->next=p;
    (*Q).rear=p;

    return OK;
}
Status DeQueue(LinkQueue *Q,BiTree *p)
{
    if(QueueEmpty(*Q))
        return ERROR;

    QueuePtr q;

    q=(*Q).front->next;
    *p=(q->data);

    (*Q).front->next=q->next;

    if((*Q).rear==q)
        (*Q).rear=(*Q).front;

    free(q);

    return OK;
}

//Traverse
void visit(ElemType e)
{
    if(e!='\0')
    printf("%c ",e);
}

Status LevelOrderTraverse(BiTree T,void(visit)(ElemType))
{
    LinkQueue Q;
    InitQueue(&Q);

    BiTree p=T;

    while(p)
    {
        visit(p->data);

        if(p->lchild) EnQueue(&Q,p->lchild);
        if(p->rchild) EnQueue(&Q,p->rchild);

        if(QueueEmpty(Q)) break;

        DeQueue(&Q,&p);

    }

    return OK;

}

Status PreOrderTraverse(BiTree T,void(visit)(ElemType))
{
    Stack S;
    InitStack(&S);

    BiTree p=T;

    while(p||!StackEmpty(S))
    {
        if(p)
        {
            visit(p->data);
            Push(&S,p);
            p=p->lchild;
        }
        else
        {
            Pop(&S,&p);
            p=p->rchild;
        }
    }

    return OK;
}
Status InOrderTraverse(BiTree T,void(visit)(ElemType))
{
    Stack S;
    InitStack(&S);

    BiTree p=T;

    while(p||!StackEmpty(S))
    {
        if(p)
        {
            Push(&S,p);
            p=p->lchild;
        }
        else
        {
            Pop(&S,&p);
            visit(p->data);
            p=p->rchild;
        }
    }

    return OK;
}
Status PostOrderTraverse(BiTree T,void(visit)(ElemType))
{
    Stack S;
    InitStack(&S);

    BiTree p=T,q;
    int tag;

    do
    {
        if(p)
        {
            Push(&S,p);
            p=p->lchild;
        }
        else
        {
            tag=TRUE;
            q=NULL;

            while(tag&&!StackEmpty(S))
            {
                GetTop(S,&p);

                if(p->rchild==q)
                {
                    visit(p->data);
                    Pop(&S,&p);
                    q=p;
                }
                else
                {
                    tag=FALSE;
                    p=p->rchild;
                }

            }
        }
    }while(!StackEmpty(S));

    return OK;
}

int main()
{
    BiTree T;

    InitBiTree(&T);
    CreateBiTree(&T);

    Print(T);
    printf("\n");

    printf("\n树的层次遍历是:\n");
    LevelOrderTraverse(T,visit);
    printf("\n");

    printf("\n树的前序遍历是:\n");
    PreOrderTraverse(T,visit);
    printf("\n");

    printf("\n树的中序遍历是:\n");
    InOrderTraverse(T,visit);
    printf("\n");

    printf("\n树的后序遍历是:\n");
    PostOrderTraverse(T,visit);
    printf("\n");

    return 0;
}


测试结果:
ABDG^^^EH^^I^^CF^J^^^
       A
   B       C
 D   E   F
G   H I   J


树的层次遍历是:
A B C D E F G H I J

树的前序遍历是:
A B D G E H I C F J

树的中序遍历是:
G D B H E I A F J C

树的后序遍历是:
G D H I E B J F C A

Process returned 0 (0x0)   execution time : 11.098 s
Press any key to continue.

发布了34 篇原创文章 · 获赞 38 · 访问量 2642

猜你喜欢

转载自blog.csdn.net/qq_43779149/article/details/104327355