zoukankan      html  css  js  c++  java
  • C语言创建二叉树数据结构, 以及各种遍历

      RT,上数据结构课时写的, 注释后面再补上.
      上课时, 听得不是很认真, 先放在这里, 等后面再来慢慢理解.
      使用时, 首先会创建根结点, 依次创建左孩子, 左孩子.
      输入0表示该结点为空.
      创建左/右孩子的时候, 又把左/右孩子当作根结点, 递归创建属于它们的左右孩子.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct BiTree{
        int data;
        struct BiTree* lchild;
        struct BiTree* rchild;
    }BiTree, *PBiTree;
    
    typedef struct Stack{
        BiTree* data[128];
        int top;
    }Stack;
    
    void stack_init(Stack* pStack)
    {
        memset(pStack, 0, sizeof(Stack));
        pStack->top = -1;
    }
    
    BiTree* stack_pop(Stack* pStack)
    {
        if(pStack->top == -1)
            return NULL;
        return pStack->data[pStack->top--];
    }
    
    BiTree* stack_get_top(Stack* pStack)
    {
        if(pStack->top == -1)
            return NULL;
        else
            return pStack->data[pStack->top];
    }
    
    int stack_push(Stack* pStack, BiTree* pBiTree)
    {
        if(pStack->top == 127)
            return 0;
        pStack->data[++pStack->top] = pBiTree;
        return 1;
    }
    
    int stack_is_empty(Stack* pStack)
    {
        return pStack->top == -1;
    }
    
    int bitree_create(BiTree** ppBiTree)
    {
        int data;
        for(;;){
            printf("输入节点的值:");
            if(scanf("%d", &data) == 1)
                break;
            fflush(stdin);
        }
        if(data == 0){
            (*ppBiTree) = NULL;
            return 1;
        }else{
            (*ppBiTree) = (PBiTree)malloc(sizeof(BiTree));
            if(!*ppBiTree){
                perror("内存分配失败");
                return 0;
            }else{
                memset(*ppBiTree, 0, sizeof(BiTree));
                (*ppBiTree)->data = data;
                bitree_create(&(*ppBiTree)->lchild);
                bitree_create(&(*ppBiTree)->rchild);
            }
        }
        return 1;
    }
    
    //释放二叉树
    void bitree_free(BiTree* pBiTree)
    {
        if(pBiTree){
            bitree_free(pBiTree->lchild);
            bitree_free(pBiTree->rchild);
            free(pBiTree);
            pBiTree = NULL;
        }
    }
    
    /*先序遍历非递归算法*/
    void PreOrderTraverse(BiTree* pBiTree)
    {
        Stack stk;
        BiTree* pb = pBiTree;
        stack_init(&stk);
        while(pb || !stack_is_empty(&stk)){
            while(pb){
                printf("%d ", pb->data);
                stack_push(&stk, pb);
                pb = pb->lchild;
            }
            pb = stack_pop(&stk);   
            pb = pb->rchild;
        }
    }
    /*先序遍历递归算法*/
    void PreOrderTraverse2(BiTree* pBiTree)
    {
        if(pBiTree){
            printf("%d ", pBiTree->data);//显示数据
            PreOrderTraverse2(pBiTree->lchild);//访问左孩子
            PreOrderTraverse2(pBiTree->rchild);//访问右孩子
        }
    }
    
    /* 中序遍历递归算法 */
    void InOrderTraverse2(BiTree* pBiTree)
    {
        if(pBiTree){
            InOrderTraverse2(pBiTree->lchild);
            printf("%d ", pBiTree->data);
            InOrderTraverse2(pBiTree->rchild);
        }
    }
    
    /* 中序遍历递归算法2 */
    void InOrderTraverse3(BiTree* pBiTree)
    {
        Stack stk;
        BiTree* pb = NULL;
        stack_init(&stk);
        pb = pBiTree;
        while(pb || !stack_is_empty(&stk)){
            if(pb){
                stack_push(&stk, pb);//根指针进栈
                pb = pb->lchild;//遍历左子树
            }else{
                //根指针出栈, 访问根结点, 遍历右子树
                pb = stack_pop(&stk);
                printf("%d ", pb->data);
                pb = pb->rchild;
            }
        }
    }
    
    /* 中序遍历非递归算法 */
    void InOrderTraverse(BiTree* pBiTree)
    {
        Stack stk;
        BiTree* pb = NULL;
        stack_init(&stk);//保存结点的栈
        stack_push(&stk, pBiTree);//根指针进栈
        while(!stack_is_empty(&stk)){
            while((pb=stack_get_top(&stk)))
                stack_push(&stk, pb->lchild);//向左走到尽头
            pb = stack_pop(&stk);//最后一个空指针出栈
            if(!stack_is_empty(&stk)){
                pb = stack_pop(&stk);//得到最后一个结点/左孩子
                printf("%d ", pb->data);
                stack_push(&stk, pb->rchild);//访问右孩子
            }
        }
    }
    
    /* 后序遍历非递归算法 */
    void PostOrderTraverse(BiTree* pBiTree)
    {
        Stack stk;
        BiTree* pb = NULL;
        BiTree* pre = NULL;
        stack_init(&stk);
        while(pBiTree || !stack_is_empty(&stk)){
            while(pBiTree){
                stack_push(&stk, pBiTree);
                pBiTree = pBiTree->lchild;
            }
            pBiTree = stack_get_top(&stk);
            if(!pBiTree->rchild || pBiTree->rchild == pre){
                printf("%d ", pBiTree->data);
                stack_pop(&stk);
                pre = pBiTree;
                pBiTree = NULL;
            }else{
                pBiTree = pBiTree->rchild;
            }
        }
    }
    
    /* 后序遍历递归算法 */
    void PostOrderTraverse2(BiTree* pBiTree)
    {
        if(pBiTree){
            PostOrderTraverse(pBiTree->lchild);
            PostOrderTraverse(pBiTree->rchild);
            printf("%d ", pBiTree->data);
        }
    }
    
    
    int main(void)
    {
        BiTree* pbt = NULL;
        bitree_create(&pbt);
        printf("\n");
        printf("先序遍历非递归算法:\t");
        PreOrderTraverse(pbt);
        printf("\n");
        printf("先序遍历递归算法:\t");
        PreOrderTraverse2(pbt);
        printf("\n");
        printf("中序遍历非递归算法:\t");
        InOrderTraverse(pbt);
        printf("\n");
        printf("中序遍历递归算法:\t");
        InOrderTraverse2(pbt);
        printf("\n");
        //printf("中序遍历递归算法2:\t");
        //InOrderTraverse3(pbt);
        //printf("\n");
        printf("后序遍历非递归算法:\t");
        PostOrderTraverse(pbt);
        printf("\n");
        printf("后序遍历递归算法:\t");
        PostOrderTraverse2(pbt);
        printf("\n");
        printf("\n");
        bitree_free(pbt);
        system("pause");
        return 0;
    }
  • 相关阅读:
    title()、upper()、lower()的用法
    Oracle用户无法访问ASM磁盘组问题
    Oracle-RAC监听服务进程关闭失败问题分析处理
    SHELL-字符串操作和变量替换
    Linux-按文件大小排序
    MySQL-重置root密码问题
    Oracle-表空间添加数据文件扩容出错解决措施
    Logstash-使用
    Logstash-工作原理
    ELK+filebeat+kafka搭建Oracle数据库日志平台
  • 原文地址:https://www.cnblogs.com/memset/p/2825551.html
Copyright © 2011-2022 走看看