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); }