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("\n");

    InOrderWithout(root,bst);
    printf("\n");
    make_empty(bst);

    PostOrderWithout(root,bst);
    make_empty(bst);
    printf("\n");

    free_tree(root,bst);

    free(bst);
}

 

posted @ 2021-10-15 14:45  州长在手  阅读(222)  评论(0编辑  收藏  举报