zoukankan      html  css  js  c++  java
  • 二叉树的基本操作小结

    转自:http://www.cnblogs.com/marrywindy/archive/2010/08/21/1805336.html

    二叉树的一般操作,实现了下:

    主要练习了二叉树的非递归遍历,利用栈,和队列来完成。算法思想,没描述清楚,表达能力很差...崩溃....


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

    测试结果:



  • 相关阅读:
    IE 11 使用 flexbox 垂直居中 bug
    Electron build 无法下载 winCodeSign 等资源
    Electron 开发环境下总是 crash
    解决 Electron 包下载太慢问题
    Netty--数据通信和心跳检测
    Netty编解码技术和UDP实现
    Netty入门
    Java 网络IO编程(BIO、NIO、AIO)
    java.util.concurrent常用类(CountDownLatch,Semaphore,CyclicBarrier,Future)
    JDK多任务执行框架(Executor框架)
  • 原文地址:https://www.cnblogs.com/youngforever/p/3104642.html
Copyright © 2011-2022 走看看