1. 目录结构
├── binary_tree.c
├── Include
│ ├── binary_tree.h
│ ├── Queue
│ │ └── queue.h
│ └── Stack
│ └── stack.h
├── Makefile
├── queue.c
├── stack.c
└── test_binary_tree.c
2. Makefile
.PHONY: clean
CC = gcc
CFLAGS = -g -Wall -DDEBUG -std = c99
C_INCLUDE_PATH = -I ./Include/ -I ./Include/Queue/ -I ./Include/Stack/
SOURCE = $( wildcard ./*.c)
BIN = test_binary_tree
$( BIN) : $( SOURCE)
$( CC) $( CFLAGS) $( EXTRA_FLAGS) $( C_INCLUDE_PATH) $( SOURCE) -o $@
clean:
rm -rf $( BIN)
3. Include/
3.1 Queue/queue.h
# ifndef __QUEUE_H__
# define __QUEUE_H__
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <errno.h>
# ifdef __cplusplus
extern "C" {
# endif
typedef void * queue_data_t;
typedef struct node_s {
queue_data_t data;
struct node_s * next;
} node_t;
typedef struct queue_s {
node_t * front;
node_t * rear;
int size;
} queue_t;
void init_queue ( queue_t * queue) ;
int get_queue_size ( const queue_t * queue) ;
int is_queue_empty ( const queue_t * queue) ;
void queue_push ( queue_t * queue, queue_data_t data) ;
void queue_pop ( queue_t * queue) ;
queue_data_t get_front ( const queue_t * queue) ;
queue_data_t get_back ( const queue_t * queue) ;
void destroy_queue ( queue_t * queue) ;
# ifdef __cplusplus
}
# endif
# endif
3.2 Stack/stack.h
# ifndef __STACK_H__
# define __STACK_H__
# include <stdio.h>
# ifdef __cplusplus
extern "C" {
# endif
# define MAX_STACK_SIZE 10
typedef void * stack_data_t;
typedef struct stack_s {
stack_data_t data[ MAX_STACK_SIZE] ;
int top;
} stack_t;
void init_stack ( stack_t * stack) ;
int get_stack_size ( const stack_t * stack) ;
int is_stack_empty ( const stack_t * stack) ;
int is_stack_full ( const stack_t * stack) ;
stack_data_t get_stack_top ( const stack_t * stack) ;
void stack_push ( stack_t * stack, stack_data_t data) ;
void stack_pop ( stack_t * stack) ;
void clear_stack ( stack_t * stack) ;
void destroy_stack ( stack_t * stack) ;
# ifdef __cplusplus
}
# endif
# endif
3.3 binary_tree.h
# ifndef __BINARY_TREE_H__
# define __BINARY_TREE_H__
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <errno.h>
# include <stdbool.h>
# ifdef __cplusplus
extern "C" {
# endif
typedef char binary_tree_data_t;
typedef struct binary_tree_s {
binary_tree_data_t data;
struct binary_tree_s * left;
struct binary_tree_s * right;
} binary_tree_t;
binary_tree_t * build_binary_tree ( binary_tree_data_t array[ ] ,
int size,
int * index) ;
void pre_order ( const binary_tree_t * root) ;
void in_order ( const binary_tree_t * root) ;
void post_order ( const binary_tree_t * root) ;
void level_order ( const binary_tree_t * root) ;
int get_binary_tree_size ( const binary_tree_t * root) ;
int get_binary_tree_leaf_size ( const binary_tree_t * root) ;
int get_binary_tree_k_layer_size ( const binary_tree_t * root, int k) ;
int get_binary_tree_height ( const binary_tree_t * root) ;
binary_tree_t * binary_tree_find_by_data ( const binary_tree_t * root,
binary_tree_data_t data) ;
bool is_complete_binary_tree ( const binary_tree_t * root) ;
void destroy_binary_tree ( binary_tree_t * root) ;
# ifdef __cplusplus
}
# endif
# endif
4. queue.c
# include "queue.h"
void init_queue ( queue_t * queue)
{
queue-> front = queue-> rear = NULL ;
queue-> size = 0 ;
}
int get_queue_size ( const queue_t * queue)
{
return queue-> size;
}
int is_queue_empty ( const queue_t * queue)
{
return 0 == get_queue_size ( queue) ;
}
void queue_push ( queue_t * queue, queue_data_t data)
{
node_t * new_node = ( node_t * ) calloc ( 1 , sizeof ( node_t) ) ;
if ( NULL == new_node) {
perror ( "calloc new_node fail" ) ;
return ;
}
new_node-> next = NULL ;
new_node-> data = data;
++ queue-> size;
if ( NULL == queue-> rear) {
queue-> front = queue-> rear = new_node;
} else {
queue-> rear-> next = new_node;
queue-> rear = new_node;
}
}
void queue_pop ( queue_t * queue)
{
if ( is_queue_empty ( queue) ) {
return ;
}
node_t * pop_node = queue-> front;
queue-> front = pop_node-> next;
free ( pop_node) ;
-- queue-> size;
if ( NULL == queue-> front) {
queue-> rear = queue-> front;
}
}
queue_data_t get_front ( const queue_t * queue)
{
if ( ! is_queue_empty ( queue) && queue-> front) {
return queue-> front-> data;
}
return NULL ;
}
queue_data_t get_back ( const queue_t * queue)
{
if ( ! is_queue_empty ( queue) && queue-> rear) {
return queue-> rear-> data;
}
return NULL ;
}
void destroy_queue ( queue_t * queue)
{
node_t * cur = queue-> front;
node_t * next_node = NULL ;
for ( ; NULL != cur; cur = next_node) {
next_node = cur-> next;
free ( cur) ;
}
queue-> front = queue-> rear = NULL ;
queue-> size = 0 ;
}
5. stack.c
# include "stack.h"
void init_stack ( stack_t * stack)
{
stack-> top = 0 ;
}
int get_stack_size ( const stack_t * stack)
{
return stack-> top;
}
int is_stack_empty ( const stack_t * stack)
{
return 0 == get_stack_size ( stack) ;
}
int is_stack_full ( const stack_t * stack)
{
return MAX_STACK_SIZE == get_stack_size ( stack) ;
}
stack_data_t get_stack_top ( const stack_t * stack)
{
return stack-> data[ stack-> top - 1 ] ;
}
void stack_push ( stack_t * stack, stack_data_t data)
{
if ( is_stack_full ( stack) ) {
return ;
}
stack-> data[ stack-> top++ ] = data;
}
void stack_pop ( stack_t * stack)
{
if ( is_stack_empty ( stack) ) {
return ;
}
-- stack-> top;
}
void clear_stack ( stack_t * stack)
{
stack-> top = 0 ;
}
void destroy_stack ( stack_t * stack)
{
clear_stack ( stack) ;
}
6. binary_tree.c
# include "binary_tree.h"
# include "queue.h"
# include "stack.h"
binary_tree_t * build_binary_tree ( binary_tree_data_t array[ ] ,
int size,
int * index)
{
binary_tree_t * root = NULL ;
do {
if ( * index >= size) {
break ;
}
if ( '#' == array[ * index] ) {
++ ( * index) ;
break ;
}
root = ( binary_tree_t * ) calloc ( 1 , sizeof ( binary_tree_t) ) ;
if ( NULL == root) {
perror ( "calloc root fail" ) ;
break ;
}
root-> data = array[ * index] ;
++ ( * index) ;
root-> left = build_binary_tree ( array, size, index) ;
root-> right = build_binary_tree ( array, size, index) ;
} while ( 0 ) ;
return root;
}
void pre_order ( const binary_tree_t * root)
{
# ifdef USE_RECURSION
if ( NULL != root) {
printf ( "%c " , root-> data) ;
pre_order ( root-> left) ;
pre_order ( root-> right) ;
}
# else
stack_t stack;
binary_tree_t * cur = ( binary_tree_t * ) root;
binary_tree_t * top = NULL ;
init_stack ( & stack) ;
while ( NULL != cur || ! is_stack_empty ( & stack) ) {
while ( NULL != cur) {
printf ( "%c " , cur-> data) ;
stack_push ( & stack, cur) ;
cur = cur-> left;
}
top = get_stack_top ( & stack) ;
stack_pop ( & stack) ;
cur = top-> right;
}
destroy_stack ( & stack) ;
# endif
}
void in_order ( const binary_tree_t * root)
{
# ifdef USE_RECURSION
if ( NULL != root) {
in_order ( root-> left) ;
printf ( "%c " , root-> data) ;
in_order ( root-> right) ;
}
# else
stack_t stack;
binary_tree_t * cur = ( binary_tree_t * ) root;
binary_tree_t * top = NULL ;
init_stack ( & stack) ;
while ( NULL != cur || ! is_stack_empty ( & stack) ) {
while ( NULL != cur) {
stack_push ( & stack, cur) ;
cur = cur-> left;
}
top = get_stack_top ( & stack) ;
printf ( "%c " , top-> data) ;
stack_pop ( & stack) ;
cur = top-> right;
}
destroy_stack ( & stack) ;
# endif
}
void post_order ( const binary_tree_t * root)
{
# ifdef USE_RECURSION
if ( NULL != root) {
post_order ( root-> left) ;
post_order ( root-> right) ;
printf ( "%c " , root-> data) ;
}
# else
stack_t stack;
binary_tree_t * cur = ( binary_tree_t * ) root;
binary_tree_t * prev = NULL ;
init_stack ( & stack) ;
while ( NULL != cur || ! is_stack_empty ( & stack) ) {
while ( NULL != cur) {
stack_push ( & stack, cur) ;
cur = cur-> left;
}
binary_tree_t * top = get_stack_top ( & stack) ;
if ( NULL != top-> right && prev != top-> right) {
cur = top-> right;
} else {
printf ( "%c " , top-> data) ;
stack_pop ( & stack) ;
prev = top;
}
}
destroy_stack ( & stack) ;
# endif
}
void level_order ( const binary_tree_t * root)
{
if ( NULL == root) {
return ;
}
queue_t queue;
binary_tree_t * queue_front = NULL ;
init_queue ( & queue) ;
queue_push ( & queue, ( queue_data_t) root) ;
while ( ! is_queue_empty ( & queue) ) {
queue_front = get_front ( & queue) ;
printf ( "%c " , queue_front-> data) ;
queue_pop ( & queue) ;
if ( NULL != queue_front-> left) {
queue_push ( & queue, ( queue_data_t) queue_front-> left) ;
}
if ( NULL != queue_front-> right) {
queue_push ( & queue, ( queue_data_t) queue_front-> right) ;
}
}
destroy_queue ( & queue) ;
}
int get_binary_tree_size ( const binary_tree_t * root)
{
if ( NULL == root) {
return 0 ;
}
return get_binary_tree_size ( root-> left) +
get_binary_tree_size ( root-> right) + 1 ;
}
int get_binary_tree_leaf_size ( const binary_tree_t * root)
{
if ( NULL == root) {
return 0 ;
}
if ( NULL == root-> left && NULL == root-> right) {
return 1 ;
}
return get_binary_tree_leaf_size ( root-> left) +
get_binary_tree_leaf_size ( root-> right) ;
}
int get_binary_tree_k_layer_size ( const binary_tree_t * root, int k)
{
if ( NULL == root || k < 1 ) {
return 0 ;
}
if ( NULL != root && 1 == k) {
return 1 ;
}
return get_binary_tree_k_layer_size ( root-> left, k - 1 ) +
get_binary_tree_k_layer_size ( root-> right, k - 1 ) ;
}
int get_binary_tree_height ( const binary_tree_t * root)
{
if ( NULL == root) {
return 0 ;
}
int left_height = get_binary_tree_height ( root-> left) ;
int right_height = get_binary_tree_height ( root-> right) ;
return left_height > right_height ?
left_height + 1 : right_height + 1 ;
}
binary_tree_t * binary_tree_find_by_data ( const binary_tree_t * root,
binary_tree_data_t data)
{
if ( NULL == root || data == root-> data) {
return ( binary_tree_t * ) root;
}
binary_tree_t * found = binary_tree_find_by_data ( root-> left, data) ;
if ( NULL != found) {
return found;
}
return binary_tree_find_by_data ( root-> right, data) ;
}
bool is_complete_binary_tree ( const binary_tree_t * root)
{
if ( NULL == root) {
return true ;
}
queue_t queue;
binary_tree_t * queue_front = NULL ;
init_queue ( & queue) ;
queue_push ( & queue, ( queue_data_t) root) ;
while ( NULL != ( queue_front = get_front ( & queue) ) ) {
queue_push ( & queue, queue_front-> left) ;
queue_push ( & queue, queue_front-> right) ;
queue_pop ( & queue) ;
}
while ( ! is_queue_empty ( & queue) ) {
queue_front = get_front ( & queue) ;
if ( NULL != queue_front) {
destroy_queue ( & queue) ;
return false ;
}
queue_pop ( & queue) ;
}
destroy_queue ( & queue) ;
return true ;
}
void destroy_binary_tree ( binary_tree_t * root)
{
if ( NULL == root) {
return ;
}
destroy_binary_tree ( root-> left) ;
destroy_binary_tree ( root-> right) ;
free ( root) ;
root = NULL ;
}
7. test_binary_tree.c
# include "binary_tree.h"
void test ( )
{
binary_tree_t * root = NULL , * found = NULL ;
int index = 0 ;
char array[ ] = {
'A' , 'B' , 'D' , '#' , '#' , '#' , 'C' , 'E' , '#' , '#' , 'F'
} ;
root = build_binary_tree ( array, sizeof ( array) / sizeof ( char ) , & index) ;
printf ( "pre_order: \n\t" ) ;
pre_order ( root) ;
printf ( "\nin_order: \n\t" ) ;
in_order ( root) ;
printf ( "\npost_order: \n\t" ) ;
post_order ( root) ;
printf ( "\nlevel_order: \n\t" ) ;
level_order ( root) ;
found = binary_tree_find_by_data ( root, 'G' ) ;
if ( NULL == found) {
printf ( "\n\nNot Found 'G'\n" ) ;
} else {
printf ( "\n\nFound %c\n" , found-> data) ;
}
if ( is_complete_binary_tree ( root) ) {
printf ( "It is complete binary tree\n" ) ;
} else {
printf ( "It is not complete binary tree\n" ) ;
}
printf ( "\nThe number of nodes in the tree: %d\n" , get_binary_tree_size ( root) ) ;
printf ( "The number of nodes in the tree leaf: %d\n" , get_binary_tree_leaf_size ( root) ) ;
printf ( "The number of nodes in the %d layer: %d\n" , 0 , get_binary_tree_k_layer_size ( root, 0 ) ) ;
printf ( "The number of nodes in the %d layer: %d\n" , 1 , get_binary_tree_k_layer_size ( root, 1 ) ) ;
printf ( "The number of nodes in the %d layer: %d\n" , 2 , get_binary_tree_k_layer_size ( root, 2 ) ) ;
printf ( "The number of nodes in the %d layer: %d\n" , 3 , get_binary_tree_k_layer_size ( root, 3 ) ) ;
printf ( "The number of nodes in the %d layer: %d\n" , 4 , get_binary_tree_k_layer_size ( root, 4 ) ) ;
printf ( "Tree height: %d\n" , get_binary_tree_height ( root) ) ;
printf ( "\ndestroy_binary_tree\n" ) ;
destroy_binary_tree ( root) ;
root = NULL ;
printf ( "Tree height: %d\n" , get_binary_tree_height ( root) ) ;
}
int main ( void )
{
test ( ) ;
return 0 ;
}