当前位置:编程学习 > C/C++ >>

数据结构-树-二叉树遍历完整可执行代码(递归/非递归)

 
#include <stdio.h>  
#include <stdlib.h>  
  
#define  MAXSIZE 20  
//二叉树结点的结构体表示形式  
typedef struct BitNode  
{  
    char    data;  
    struct BitNode* left,*right;  
}BitTree;  
  
//栈的结构体表示形式  
typedef struct stackelem  
{  
    BitTree* a[MAXSIZE];  
    int top;  
}Stack;  
  
//队列的结构体的表示形式  
typedef struct queueelem  
{  
    BitTree* b[MAXSIZE];  
    int front,rear;  
}Queue;  
  
//创建二叉树,利用递归的方法  
//按前序次序输入。 如 A # #(#表示空树)  
BitTree* Create()  
{  
    char ch;  
    scanf("%c",&ch);  
    getchar();    //吃掉空格符  
    if (ch=='#')  
    {  
        return NULL;  
    }  
    else  
    {  
        BitTree* btree=(BitTree*)malloc(sizeof(BitTree));  
        if (NULL==btree)  
        {  
            return NULL;  
        }  
        btree->data=ch;  
        btree->left=Create();  
        btree->right=Create();  
        return btree;  
    }  
}  
  
//前序遍历,递归的方法  
void Preorder(BitTree* bt)  
{  
    if (NULL!=bt)  
    {  
        printf("%c ",bt->data);  
        Preorder(bt->left);  
        Preorder(bt->right);  
    }  
}  
  
//前序遍历的非递归实现  
/* 
 思想:利用栈来实现;根结点进栈,之后栈非空,弹出,接着根节点的右结点进栈,之后,左节点进栈;接着,弹出栈顶元素(输出), 
 此结点的右结点进栈,之后左节点进栈,弹出栈顶元素(输出)...一直这样下去,直到栈为空。 
 */  
void Preorder2(BitTree* bt)  
{  
    BitTree* p;  
    Stack st;  
    st.top=-1;  
    if (NULL==bt)  
    {  
        return;  
    }  
    else  
    {  
        st.top++;  
        st.a[st.top]=bt;  
        while (st.top!=-1)  
        {  
            p=st.a[st.top];  
            st.top--;  
            printf("%c ",p->data);  
            if (p->right!=NULL)  
            {  
                st.top++;  
                st.a[st.top]=p->right;  
            }  
            if (p->left!=NULL)  
            {  
                st.top++;  
                st.a[st.top]=p->left;  
            }  
        }  
    }  
}  
  
//中序遍历,递归实现  
void Inorder(BitTree* bt)  
{  
    if (NULL!=bt)  
    {  
        Inorder(bt->left);  
        printf("%c ",bt->data);  
        Inorder(bt->right);  
    }  
}  
  
//中序遍历,非递归实现  
/* 
 思想:利用栈。从根节点开始,循环,只要有左子节点则进栈,直到左子节点为空。接着弹出栈顶输出,判断该结点是否有右子节点, 
 若有则进栈,若没有继续弹栈。有右子节点的情况,判断该节点是否有左子节点,有则进栈,直到左子节点为空;若该右子节点没有 
 左子节点,则弹栈;判断弹出的节点,是否有右子节点,若有则进栈,没有继续弹栈;接着又要判断刚进栈的这个节点,是否有左子节点, 
 有则进栈,没有则继续弹栈。重复下去.... 
 栈空,是判定条件。 
 */  
void Inorder2(BitTree* bt)  
{  
    BitTree* p,*q;  
    Stack st;  
    st.top=-1;  
    if (NULL==bt)  
    {  
        return;  
    }  
    else  
    {  
        while (bt!=NULL)  
        {  
            st.top++;  
            st.a[st.top]=bt;  
            bt=bt->left;  
        }  
        while (st.top!=-1)  
        {  
            p=st.a[st.top];  
            st.top--;  
            printf("%c ",p->data);  
            while ( p->right!=NULL )  
            {  
                st.top++;  
                st.a[st.top]=p->right;  
                q=p->right;  
                while (q->left!=NULL)  
                {  
                    st.top++;  
                    st.a[st.top]=q->left;  
                    q=q->left;  
                }  
                break;  
            }  
        }  
    }  
}  
  
//后序遍历,递归实现  
void Postorder(BitTree* bt)  
{  
    if (bt!=NULL)  
    {  
        Postorder(bt->left);  
        Postorder(bt->right);  
        printf("%c ",bt->data);  
    }  
}  
  
//后序遍历,非递归实现  
/* 
 算法思想:利用栈来实现。从根结点开始,只要左子节点非空,则进栈,直到左子节点为空为止。取出栈顶元素(只是取,并非弹栈),判断 
 1:取出的栈顶元素是否有右子节点,或者右子节点是否被访问过,若满足条件(无右子节点,或者右子节点被访问过),则输出该结点, 
 同时弹栈,并且记录下该访问的节点。 
 2:取出的栈顶元素,若有右子节点,且未被访问过,则指针继续移动到右子节点,重复一开始是否又左子节点的判断。 
 */  
void Postorder2(BitTree* bt)  
{  
    Stack st;  
    st.top=-1;  
    BitTree* t;  
    do  
    {  
        while (bt!=NULL)  
        {  
            st.top++;  
            st.a[st.top]=bt;  
            bt=bt->left;  
        }  
        t=NULL;  
        while (st.top!=-1)  
        {  
            bt=st.a[st.top];  
            if (bt->right==t)  //t:表示为null,或者右子节点被访问过了。  
            {  
                printf("%c ",bt->data);  
                st.top--;  
                t=bt;  //t记录下刚刚访问的节点  
            }  
            else  
            {  
                bt=bt->right;  
                break;  
            }  
        }  
    } while (st.top!=-1);  
}  
  
//求二叉树的高度,递归实现  
int Height(BitTree* bt)  
{  
    int depth1,depth2;  
    if (NULL==bt)  
    {  
        return 0;  
    }  
    else  
    {  
        depth1=Height(bt->left);  
        depth2=Height(bt->right);  
        if (depth1>depth2)  
        {  
            return (depth1+1);  
        }  
        else  
        {  
            return (depth2+1);  
        }  
    }  
}  
  
//层次遍历二叉树,用队列来实现  
void TraversalOfLevel(BitTree* bt)  
{  
    Queue q;  
    q.front=q.rear=0;  
    if (bt!=NULL)  
    {  
        printf("%c ",bt->data);  
    }  
    q.b[q.front]=bt;  
    q.rear=q.rear+1;  
    while (q.front<q.rear)  
    {  
        bt=q.b[q.front];  
        q.front=q.front+1;  
        if (bt->left!=NULL)  
        {  
            printf("%c ",bt->left->data);  
            q.b[q.rear]=bt->left;  
            q.rear=q.rear+1;  
        }  
        if (bt->right!=NULL)  
        {  
            printf("%c ",bt->right->data);  
            q.b[q.rear]=bt->right;  
            q.rear=q.rear+1;  
        }  
    }  
}  
  
int main()  
{  
    BitTree* btr=Create();  
    printf("前序遍历:递归和非递归实现:\n");  
    Preorder(btr);  
    printf("\n");  
    Preorder2(btr);  
    printf("\n");  
    printf("中序遍历:递归和非递归实现:\n");  
    Inorder(btr);  
    printf("\n");  
    Inorder2(btr);  
    printf("\n");  
    printf("后序遍历:递归和非递归实现:\n");  
    Postorder(btr);  
    printf("\n");  
    Postorder2(btr);  
    printf("\n");  
    printf("二叉树的高度:\n");  
    int Hgt=Height(btr);  
    printf("%d \n",Hgt);  
    printf("层次遍历二叉树:\n");  
    TraversalOfLevel(btr);  
    printf("\n");  
    return 0;  
}  
  
/*  测试数据:   
 d b a # # c # # f e # # g # # 
 前序遍历:递归和非递归实现: 
 d b a c f e g 
 d b a c f e g 
 中序遍历:递归和非递归实现: 
 a b c d e f g 
 a b c d e f g 
 后序遍历:递归和非递归实现: 
 a c b e g f d 
 a c b e g f d 
 二叉树的高度: 
 3 
 层次遍历二叉树: 
 d b f a c e g 
 
*/  

 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,