二叉树 - 链表实现 - C语言

实现了二叉树的前序遍历,中序遍历,后序遍历,逐层遍历。

其中逐层遍历,使用了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;
}


猜你喜欢

转载自blog.csdn.net/weixin_42263483/article/details/80905188