zoukankan      html  css  js  c++  java
  • C 语言实现栈,遍历二叉树和释放二叉树

    详细参考链接和解析

    下面是代码: library.h

      头文件

    #ifndef FOURC_LIBRARY_H
    #define FOURC_LIBRARY_H
    #include <stdbool.h>
    #include <stdlib.h>
    #include <stdio.h>
    #define MAX_NODE 10
    
    // 树的定义
    typedef struct TreeNode {
        int val;
        struct TreeNode * left;
        struct TreeNode * right;
    }tree_node;
    
    // 定义适配树的栈
    typedef struct TreeStack{
        int size;
        int top;
        tree_node  * contents[MAX_NODE];
    }tree_stack;
    
    // 使用后free
    tree_stack * creat_tree_stack();
    void make_empty(tree_stack *);
    bool is_empty(tree_stack *);
    bool is_full(tree_stack *);
    void push(tree_stack *,tree_node *);
    tree_node* pop(tree_stack *);
    
    /*
     *                 1
     *      2                   3
     *  4      5             6     7
     *    8
     *  9
     */
    
    
    struct TreeNode *create_tree();
    struct TreeNode *create_nod(int);
    //
    void PerOrderWithout(struct TreeNode *root ,struct TreeStack *ts);
    //
    void InOrderWithout(struct TreeNode *root,struct TreeStack *ts);
    //
    void PostOrderWithout(struct TreeNode *root,struct TreeStack *ts);
    
    // 释放掉树,使用前序遍历
    void free_tree(struct TreeNode * root,struct TreeStack *ts);
    
    #endif //FOURC_LIBRARY_H

    实现文件: library.c

    #include "library.h"
    
    // ------------------------------- STACK START -------------------------------
    tree_stack * creat_tree_stack(){
        return malloc(sizeof(tree_stack));
    }
    
    void make_empty(tree_stack* ts){
        ts->top =0;
    }
    
    bool is_empty(tree_stack* ts){
        return ts->top == 0;
    }
    
    bool is_full(tree_stack*ts){
        return ts->top == MAX_NODE;
    }
    
     void push(tree_stack *ts , tree_node * tn){
        if (is_full(ts))
            return;
    
        ts->contents[(ts->top)++] = tn;
    }
    
    tree_node * pop(tree_stack *ts ){
        if (is_empty(ts))
            NULL;
        return ts->contents[--(ts->top)];
    }
    
    // ------------------------------- STACK END -------------------------------
    struct TreeNode *create_tree() {
        struct TreeNode *t1 = create_nod(1);
        struct TreeNode *t2 = create_nod(2);
        struct TreeNode *t3 = create_nod(3);
        struct TreeNode *t4 = create_nod(4);
        struct TreeNode *t5 = create_nod(5);
        struct TreeNode *t6 = create_nod(6);
        struct TreeNode *t7 = create_nod(7);
        struct TreeNode *t8 = create_nod(8);
        struct TreeNode *t9 = create_nod(9);
        t1->left = t2;
        t1->right = t3;
    
        t2->left = t4;
        t2->right = t5;
    
        t3->left = t6;
        t3->right = t7;
    
        t4->right = t8;
    
        t8->left = t9;
        return t1;
    }
    
    struct TreeNode *create_nod(int val) {
        struct TreeNode *t = (struct TreeNode *) malloc(sizeof(struct TreeNode));
        t->val = val;
        t->left = NULL;
        t->right = NULL;
        return t;
    }
    
    void PerOrderWithout(struct TreeNode *root,struct TreeStack *bst) {
        struct TreeNode *curr = root;
      //  tree_stack *bst = creat_tree_stack();
        while (!is_empty(bst) || curr != NULL) {
            while (curr != NULL) {
                //边遍历边打印,并存入栈中,以后需要借助这些根节点(不要怀疑这种说法哦)进入右子树
                printf("%d ", curr->val);
                push(bst, curr);
                curr = curr->left;
            }
            //当p为空时,说明根和左子树都遍历完了,该进入右子树了
            curr = pop(bst);
            curr = curr->right;
        }
    }
    
    void InOrderWithout(struct TreeNode *root,struct TreeStack *bst) {
        struct TreeNode *curr = root;
        while (!is_empty(bst) || curr != NULL) {
            //一直遍历到左子树最下边,边遍历边保存根节点到栈中
            while (curr != NULL) {
                push(bst, curr);
                curr = curr->left;
            }
            //当p为空时,说明已经到达左子树最下边,这时需要出栈了
            curr = pop(bst);
            printf("%d ", curr->val);
            //进入右子树,开始新的一轮左子树遍历(这是递归的自我实现)
            curr = curr->right;
        }
    }
    
    void PostOrderWithout(struct TreeNode *root,struct TreeStack *bst) {
     //   tree_stack *bst = creat_tree_stack();
        //pCur:当前访问节点,pLastVisit:上次访问节点
        struct TreeNode *curr, *pLast_visit;
        curr = root;
        pLast_visit = NULL;
        // 先便利到最左边
        while (curr != NULL) {
            push(bst, curr);
            curr = curr->left;
        }
        while (!is_empty(bst)){
            curr = pop(bst);
            //一个根节点被访问的前提是:无右子树或右子树已被访问过
            if(curr->right == NULL || curr->right == pLast_visit){
                printf("%d ",curr->val);
                pLast_visit = curr;
            } else {
                //根节点再次入栈
                push(bst, curr);
                curr = curr->right;
                while (curr != NULL){
                    push(bst,curr);
                    curr = curr->left;
                }
            }
        }
    
        //free(bst);
    }
    
    void free_tree(struct TreeNode * root ,tree_stack * bst){
        struct TreeNode * t = NULL;
        while (!is_empty(bst) || root != NULL){
            while (root != NULL){
                push(bst,root);
                root = root->left;
            }
            root = pop(bst);
            t = root;
            root =root->right;
            free(t);
        }
    }

    main.c

    //
    // Created by ct on 2021/10/15.
    //
    #include "library.h"int main(int argc, char *argv[]) {
        tree_node *root = create_tree();
        struct TreeStack *bst = creat_tree_stack();
    
    
        PerOrderWithout(root,bst);
        make_empty(bst);
        printf("
    ");
    
        InOrderWithout(root,bst);
        printf("
    ");
        make_empty(bst);
    
        PostOrderWithout(root,bst);
        make_empty(bst);
        printf("
    ");
    
        free_tree(root,bst);
    
        free(bst);
    }
  • 相关阅读:
    tidb3.2参数优化配置整个过程
    tidb优化配置
    mysql使用docker安装
    mysql密码规则配置-配置为简单密码123456
    goaccess日志分析器使用
    c# printDialog不显示问题
    short数组写进txt
    txt文件存储问题
    c# 调用c++dll二次总结
    程序员代码开发的自测素养
  • 原文地址:https://www.cnblogs.com/Addoil/p/15411017.html
Copyright © 2011-2022 走看看