• 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;
    }
  • 相关阅读:
    【转】Android-Input input&按键布局文件
    【转】Android-Input 触摸设备
    【转】IE沙箱拖拽安全策略解析
    FireFox 插件xpi文件签名2
    如何给Firefox附加组件签名
    【转】用opencv使摄像头在30fps下捕获1080p的数据
    Displaylink安卓驱动
    无主之地2 不费子弹手枪
    jsoncpp
    [APIO2010] 算法竞赛竞赛经典 巡逻
  • 原文地址:https://www.cnblogs.com/memset/p/2825551.html
Copyright © 2020-2023  润新知