实现了二叉树的前序遍历,中序遍历,后序遍历,逐层遍历。
其中逐层遍历,使用了TreeQueue.h里面定义的队列Queue。
因此,程序由两个文件组成,BinaryTree.c和TreeQueue.h。
程序输出:
$ ./BinaryTree
*****Tree*****
+
* /
a b c d
**************
PreOrder:
+ * a b / c d
InOrder:
a * b + c / d
PostOrder:
a b * c d / +
LevelOrder:
+ * / a b c d
BinaryTree.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TreeQueue.h"
static void visit(struct tree_node *n);
static struct tree_node * create_node(char *data);
static void pre_order(struct tree_node *n);
static void in_order(struct tree_node *n);
static void post_order(struct tree_node *n);
static void level_order(struct tree_node *n);
static void visit(struct tree_node *n)
{
if(NULL == n || NULL == n->data)
return;
printf("%s ", n->data);
}
static struct tree_node * create_node(char *data)
{
int len = 0;
struct tree_node *node;
node = malloc(sizeof(struct tree_node));
if(NULL == node)
return NULL;
memset(node, 0, sizeof(struct tree_node));
if(data) {
node->data = malloc(strlen(data)+1);
memset(node->data, 0, strlen(data)+1);
strncpy(node->data, data, strlen(data));
} else {
node->data = NULL;
}
node->left = NULL;
node->right = NULL;
return node;
}
/*
* 采用后序遍历的方式,依次free每个节点
*/
static void destroy_tree(struct tree_node *root)
{
if(root) {
destroy_tree(root->left);
destroy_tree(root->right);
free(root->data);
}
}
/*
* 前序遍历
*/
static void pre_order(struct tree_node *n)
{
if(n) {
visit(n);
pre_order(n->left);
pre_order(n->right);
}
}
/*
* 中序遍历
*/
static void in_order(struct tree_node *n)
{
if(n) {
in_order(n->left);
visit(n);
in_order(n->right);
}
}
/*
* 后序遍历
*/
static void post_order(struct tree_node *n)
{
if(n) {
post_order(n->left);
post_order(n->right);
visit(n);
}
}
/*
* 逐层遍历
*/
static void level_order(struct tree_node *n)
{
struct tree_node *node;
Queue queue;
q_init(&queue, 10);
node = n;
while(node) {
visit(node);
if(node->left)
queue.enqueue(&queue, node->left);
if(node->right)
queue.enqueue(&queue, node->right);
node = NULL;
queue.dequeue(&queue, &node);
}
queue.destroy(&queue);
}
static void printf_tree()
{
printf("*****Tree*****\n");
printf(" +\n");
printf(" * /\n");
printf("a b c d\n");
printf("**************\n\n");
}
/*
* Test code
*/
int main()
{
/* Create root node */
struct tree_node *root = NULL;
root = create_node("+");
root->left = create_node("*");
root->right = create_node("/");
root->left->left = create_node("a");
root->left->right = create_node("b");
root->right->left = create_node("c");
root->right->right = create_node("d");
printf_tree();
/* Visit */
printf("PreOrder:\n");
pre_order(root);
printf("\n\n");
printf("InOrder:\n");
in_order(root);
printf("\n\n");
printf("PostOrder:\n");
post_order(root);
printf("\n\n");
printf("LevelOrder:\n");
level_order(root);
printf("\n\n");
/* Free */
destroy_tree(root);
return 0;
}
TreeQueue.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RET_TRUE 0
#define RET_FALSE -1
typedef struct Queue Queue;
struct tree_node {
char *data;
struct tree_node *left;
struct tree_node *right;
};
struct Queue {
struct tree_node **data;
int max_q_size;
int enq_pos; /* The index of element to be enqueued */
int deq_pos; /* The index of element to be dequeued */
int ele_nums; /* The count of element in queue */
int (*enqueue)(Queue *q, struct tree_node *ele);
int (*dequeue)(Queue *q, struct tree_node **ele);
int (*is_empty)(Queue *q);
int (*is_full)(Queue *q);
void (*destroy)(Queue *q);
};
static int q_is_empty(Queue *q)
{
if(NULL == q)
return RET_FALSE;
if(q->ele_nums == 0)
return RET_TRUE;
return RET_FALSE;
}
static int q_is_full(Queue *q)
{
if(NULL == q)
return RET_FALSE;
if(q->ele_nums == q->max_q_size)
return RET_TRUE;
return RET_FALSE;
}
static int q_enqueue(Queue *q, struct tree_node *ele)
{
if(NULL == q || NULL == ele || q->is_full(q) == RET_TRUE)
return RET_FALSE;
q->data[q->enq_pos] = ele;
q->ele_nums++;
q->enq_pos++;
if(q->enq_pos == q->max_q_size)
q->enq_pos = 0;
return RET_TRUE;
}
static int q_dequeue(Queue *q, struct tree_node **ele)
{
struct tree_node *q_ele;
if(NULL == q || q->is_empty(q) == RET_TRUE)
return RET_FALSE;
*ele = q->data[q->deq_pos];
q->data[q->deq_pos] = NULL;
q->ele_nums--;
q->deq_pos++;
if(q->deq_pos == q->max_q_size)
q->deq_pos = 0;
return RET_TRUE;
}
static void q_destroy(Queue *q)
{
int i;
if(NULL == q || NULL == q->data)
return;
free(q->data);
q->data = NULL;
}
static int q_init(Queue *q, int size)
{
if(NULL == q || size <= 0)
return RET_FALSE;
q->data = malloc(size*sizeof(struct tree_node *));
if(q->data == NULL) {
printf("q_init: malloc fail for q->data, size=%d\n", size);
return RET_FALSE;
}
q->max_q_size = size;
q->enq_pos = 0; /* The first enqueue element will be store at index 0 */
q->deq_pos = 0;
q->ele_nums = 0;
q->enqueue = q_enqueue;
q->dequeue = q_dequeue;
q->is_empty = q_is_empty;
q->is_full = q_is_full;
q->destroy = q_destroy;
return RET_TRUE;
}