二叉树的先序,中序,后序及其非递归遍历的方法

13年大一第二学期学数据结构的时候写的了,今天发现草稿箱里面有这篇,就顺手发出来了。程序里面有二叉树先序遍历,后序遍历,中序遍历及其非递归遍历的方法,还有层次遍历跟查找某个节点的路径的方法,涉及到的数据结构有二叉树,栈跟队列。其实还有一些缺陷,有时间再去改正吧,不过对于学习理解还是不错的。

# include <stdio.h>
# include <stdlib.h>
# include <conio.h>
# define STACKSIZE 100

typedef char TElemType;

typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}*BiTree,BiTNode;

typedef BiTree SElemType;

typedef struct
{
    SElemType data[STACKSIZE];
    int top;
}SeqStack;

typedef BiTree QElemType;

typedef struct node
{
    QElemType data;
    struct node *next;
}QNode,*QNodeptr;

typedef struct 
{
    QNode *front;
    QNode *rear;
}*LinkQueue,Queue;

/*对队列进行初始化操作*/ 
void InitQueue(LinkQueue *Q)
{
    (*Q) = (LinkQueue)malloc(sizeof(Queue));
    (*Q)->front = (QNode *)malloc(sizeof(QNode));
    if(!(*Q)->front)
    {
        printf("Memory error!\n");
        exit(0);
    }
    (*Q)->rear = (*Q)->front;
    (*Q)->rear->next = NULL;
}

/*入队操作*/ 
void EnQueue(LinkQueue *Q,QElemType value)
{
    QNode *temp;
    temp = (QNodeptr)malloc(sizeof(QNode));
    if(!temp)
    {
        printf("memroy error!\n");
        exit(0);
    }
    temp->data = value;
    temp->next = NULL;
    (*Q)->rear->next = temp;
    (*Q)->rear = temp;
}

/*出队操作*/ 
void DeQueue(LinkQueue *Q,QElemType *x)
{
    QNode *temp;
    /*
    temp = (QNodeptr)malloc(sizeof(QNode));
    if(!temp)
    {
        printf("memroy error!\n");
        exit(0);
    }
    */
    temp = (*Q)->front->next;
    *x = temp->data;
    (*Q)->front->next = temp->next;
    if((*Q)->rear==temp)
      (*Q)->rear=(*Q)->front;
    free(temp);
}

/*判断队列是否为空*/
int  EmptyQueue(LinkQueue Q)
{
    if(Q->front == Q->rear)
        return 1;
    else
        return 0;    
}

/*初始化一个栈*/ 
void InitStack(SeqStack *S)
{
    S->top = 0;
}

/*将val入栈*/ 
int  Push(SeqStack *S,SElemType val)
{
    if(S->top >= STACKSIZE)
        {
            printf("栈已满,入栈失败!\n");
            return 0;
        }
    S->data[S->top] = val;
    S->top++;    
}

/*对栈内元素进行输出*/
int Output(SeqStack S)
{
    int i;
    if(S.top == 0)
    {
        printf("未找到该节点!");
        return 0;
    }    
    else
    {
        printf("该节点的路径为:\n");
        for(i = 0;i < S.top;i++)
        {
            printf("%c",S.data[i]->data);
            if(i != S.top-1)
                printf("->");
        }
    }
} 

/*出栈操作,将出栈的值赋给x*/ 
int Pop(SeqStack *S,SElemType *x)
{
    if(S->top == 0)
    {
        printf("栈为空,出栈失败!\n");
        return 0;
    }
    S->top--;
    *x = S->data[S->top];    
}

/*判断栈是否为空*/
int StackEmpty(SeqStack S)
{
    if(S.top==0)  
      return 1;
    else
      return 0; 
} 

/*得到栈顶元素*/ 
int GetTop(SeqStack S,SElemType *x)
{
    if(S.top == 0)
    {
        printf("栈为空!\n");
        return 0;
    }
    else
        *x = S.data[S.top-1];
}


/*清空缓冲区*/ 
void flush()
{
    while(getchar() != '\n');
}

/*初始化一个二叉树*/ 
void InitBiTree(BiTree *T)
{
    *T = NULL;
}

/*递归先序创建一颗二叉树*/
void CreateBiTree(BiTree *T)
{
    char ch;
    printf("ch =");
    scanf("%c",&ch);
    flush();
    if(ch == ' ')
        *T=NULL;
    else
    {
        *T = (BiTree)malloc(sizeof(BiTNode));
        (*T)->data = ch;
        CreateBiTree(&(*T)->lchild);
        CreateBiTree(&(*T)->rchild);
    }
}

/*非递归先序遍历二叉树*/
void PreTraverse(BiTree T)
{
    SeqStack S;
    InitStack(&S);
    Push(&S,T);
    while(!StackEmpty(S))
    {
        Pop(&S,&T);
        printf("%c ",T->data);
        if(T->rchild)
            Push(&S,T->rchild);
        if(T->lchild)
            Push(&S,T->lchild);    
    }
}

/*先序递归遍历二叉树*/
void PreOrderTraverse(BiTree T)
{
    if(T)
    {
        printf("%c ",T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
} 

/*递归中序遍历二叉树*/
void InOrderTraverse(BiTree T)
{
    if(T)
    {
        PreOrderTraverse(T->lchild);
        printf("%c ",T->data);
        PreOrderTraverse(T->rchild);
    }
} 

/*非递归中序输出*/ 
void InTraverse(BiTree T)
{
    SeqStack S;
    InitStack(&S);
    while(T || !StackEmpty(S))
    {
        if(T)
        {
            Push(&S,T);
            T = T->lchild; 
        }
        else
        {
            Pop(&S,&T);
            printf("%c ",T->data);
            T = T->rchild;
        }
    }
}

/*递归后序遍历二叉树*/ 
void PostOrderTraverse(BiTree T)
{
    if(T)
    {
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
        printf("%c ",T->data);
    }
}

/*水平遍历一个二叉树*/
void  LeverlOrderTraverse(BiTree T)
{
    LinkQueue Q;
    QElemType a;
    if(T)
    {
        InitQueue(&Q);
        EnQueue(&Q,T);
        while(!EmptyQueue(Q))
        {
            DeQueue(&Q,&a);
            printf("%c ",a->data);
            if(a->lchild!=NULL)
                EnQueue(&Q,a->lchild);
            if(a->rchild!=NULL)
                EnQueue (&Q,a->rchild);
        }
    }
}

/*查找节点的路径*/ 
SeqStack SearchPath(BiTree T,TElemType val)
{
    SeqStack S;
    InitStack(&S);
    int flag = 0;
    BiTree ht;
    Push(&S,T);
    while(!StackEmpty(S))
    {
        GetTop(S,&ht);
        if(ht->data == val)
            {
                //printf("%c",ht->data);
                return S;
                break;
            }
        else if(flag == 0)
        {
            if(/*ht->data != val && */ht->lchild != NULL)
                Push(&S,ht->lchild);
            else 
                flag = 1;    
        }
        else 
        {
            if(ht->rchild != NULL)
            {
                Push(&S,ht->rchild);
                flag = 0;
            }
            else
            {
                Pop(&S,&T);
                while(!StackEmpty(S))
                {
                    GetTop(S,&ht);
                    if(ht->rchild != T)
                        break;
                    Pop(&S,&T);    
                }
            }
        }
    }
}

int Menu(BiTree T)
{
    char i;
    do
    {
        system("cls");
        printf("******************************************************************\n");
        printf("*\t\t请选择:\n*\n");
        printf("*\t\t1.先序递归遍历二叉树\n");
        printf("*\t\t2.先序非递归遍历二叉树\n");
        printf("*\t\t3.中序递归遍历二叉树\n");
        printf("*\t\t4.中序非递归遍历二叉树\n");
        printf("*\t\t5.后序递归遍历二叉树\n");
        printf("*\t\t6.层次遍历二叉树\n");
        printf("*\t\t7.查找二叉树中某个节点的路径\n");
        printf("*\t\t0.结束\n");
        printf("******************************************************************\n");
        printf("请输入你的选择:\n");
        scanf("%c",&i);
        flush();
        if(i == '0')
        {
            printf("\t\t\t感谢使用!\n");
            break;
        }    
        else
            switch(i)
            {
                case '1':
                        printf("先序递归遍历二叉树的结果为:\n");
                        PreOrderTraverse(T);
                        printf("\n请按回车键或者任意键继续!\n"); 
                        getch();
                        break;
                case '2':
                        printf("先序非递归遍历二叉树的结果为:\n");
                        PreTraverse(T);
                        printf("\n请按回车键或者任意键继续!\n");
                        getch();
                       break;
                case '3':
                        printf("中序递归遍历二叉树的结果为:\n");
                         InOrderTraverse(T);
                           printf("\n请按回车键或者任意键继续!\n");
                           getch();
                           break;
                case '4':
                        printf("中序非递归遍历二叉树的结果为:\n");
                        InTraverse(T);
                           printf("\n请按回车键或者任意键继续!\n");
                           getch();
                           break;
                case '5':
                        printf("后序递归遍历二叉树的结果为:\n");
                        PostOrderTraverse(T);
                           printf("\n请按回车键或者任意键继续!\n");
                           getch();
                           break;
                case '6': 
                        printf("层次遍历二叉树的结果为:\n");
                        LeverlOrderTraverse(T);
                           printf("\n请按回车键或者任意键继续!\n");
                           getch();
                           break;
                case '7':
                        SeqStack S;
                        char ch;
                        InitStack(&S);
                        printf("请输入要查找的节点:\n");
                        scanf("%c",&ch);
                        flush();    
                        S = SearchPath(T,ch);
                        Output(S);
                        printf("\n请按回车键或者任意键继续!\n");
                           getch();
                        break;       
                default:
                    printf("\007\t\t输入错误,请重新输入!\n");
                    printf("\n\t\t请按回车键或者任意键继续!\n");
                    getch();
            }    
    }        
    while(i != '0');             
}

int main()
{
    BiTree T;
    InitBiTree(&T);
    printf("请先创建一个二叉树:\n");
    CreateBiTree(&T);
    Menu(T);
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值