算法导论C语言实现: 二叉搜索树(binary tree)

1. 源代码

ia_binarytree.h

#ifndef __IA_BINARY_TREE_H__
#define __IA_BINARY_TREE_H__

#include <common.h>

typedef struct _binary_tree_node_t {
	int key;
	struct _binary_tree_node_t *p;
	struct _binary_tree_node_t *left;
	struct _binary_tree_node_t *right;
} binary_tree_node_t;

typedef struct _binary_tree_t {
	binary_tree_node_t *root;
} binary_tree_t;


void ia_binary_tree_inorder_walk(binary_tree_node_t *x, FILE *f);

binary_tree_node_t *ia_binary_tree_search(binary_tree_node_t *x, int k);

binary_tree_node_t *ia_binary_tree_iterative_search(binary_tree_node_t *x, int k);

//x must not be NIL(NULL)
binary_tree_node_t *ia_binary_tree_minimum(binary_tree_node_t *x);

//x must not be NIL(NULL)
binary_tree_node_t *ia_binary_tree_maximum(binary_tree_node_t *x);

binary_tree_node_t *ia_binary_tree_successor(binary_tree_node_t *x);

binary_tree_node_t *ia_binary_tree_predecessor(binary_tree_node_t *x);

void ia_binary_tree_insert(binary_tree_t *T, binary_tree_node_t *z);

void ia_binary_tree_delete(binary_tree_t *T, binary_tree_node_t *z);

#endif	/* __IA_BINARY_TREE_H__ */

ia_binarytree.c

#include <ia_binarytree.h>

void ia_binary_tree_inorder_walk(binary_tree_node_t *x, FILE *f)
{
	const char* s_1 = "child {\nnode [arn_n] {";
	const char* s_1_space = "child {\nnode [arn_x] {";
	const char* s_2 = "}\n";
	//const char* s_3 = "}\r\n";
	char s_v[20];

	if (x != NIL) {
		if (f == NULL) {
			ia_binary_tree_inorder_walk(x->left, f);
			TRACE(" %d", x->key);
			ia_binary_tree_inorder_walk(x->right, f);
		} else {
			sprintf_s(s_v, sizeof(s_v), "%d", x->key);
			fputs(s_1, f);
			fputs(s_v, f);
			fputs(s_2, f);

			//print children
			ia_binary_tree_inorder_walk(x->left, f);
			ia_binary_tree_inorder_walk(x->right, f);

			fputs(s_2, f);
		}
	} else {
		if (f != NULL) {
			fputs(s_1_space, f);
			fputs(s_2, f);
			fputs(s_2, f);
		}
	}
}

binary_tree_node_t *ia_binary_tree_search(binary_tree_node_t *x, int k)
{
	if (x == NIL || k == x->key) {
		return x;
	}
	if (k < x->key) {
		return ia_binary_tree_search(x->left, k);
	} else {
		return ia_binary_tree_search(x->right, k);
	}
}

binary_tree_node_t *ia_binary_tree_iterative_search(binary_tree_node_t *x, int k)
{
	while (x != NIL && k != x->key) {
		x = (k < x->key)?x->left:x->right;
	}

	return x;
}

//x must not be NIL(NULL)
binary_tree_node_t *ia_binary_tree_minimum(binary_tree_node_t *x)
{
	while (x->left != NIL) {
		x = x->left;
	}

	return x;
}

//x must not be NIL(NULL)
binary_tree_node_t *ia_binary_tree_maximum(binary_tree_node_t *x)
{
	while (x->right != NIL) {
		x = x->right;
	}

	return x;
}

binary_tree_node_t *ia_binary_tree_successor(binary_tree_node_t *x)
{
	binary_tree_node_t *y = NIL;

	if (x->right != NIL) {
		return ia_binary_tree_minimum(x->right);
	}

	y = x->p;
	while (y != NIL && x == y->right) {
		x = y;
		y = y->p;
	}

	return y;
}

binary_tree_node_t *ia_binary_tree_predecessor(binary_tree_node_t *x)
{
	binary_tree_node_t *y = NIL;

	if (x->left != NIL) {
		return ia_binary_tree_maximum(x->left);
	}

	y = x->p;
	while (y != NIL && x == y->left) {
		x = y;
		y = y->p;
	}

	return y;
}

void ia_binary_tree_insert(binary_tree_t *T, binary_tree_node_t *z)
{
	binary_tree_node_t *x = T->root;
	binary_tree_node_t *y = NIL;

	while (x != NIL) {
		y = x;
		if (z->key < x->key) {
			x = x->left;
		} else {
			x = x->right;
		}
	}

	z->p = y;
	if (y == NIL) {
		T->root = z;		//tree T is empty
	} else if (z->key < y->key) {
		y->left = z;
	} else {
		y->right = z;
	}
}

static void ia_binary_tree_transplant(
	binary_tree_t *T,
	binary_tree_node_t *u,
	binary_tree_node_t *v)
{
	if (u->p == NIL) {
		T->root = v;
	} else if (u == u->p->left) {
		u->p->left = v;
	} else {
		u->p->right = v;
	}

	if (v != NIL) {
		v->p = u->p;
	}
}

void ia_binary_tree_delete(binary_tree_t *T, binary_tree_node_t *z)
{
	binary_tree_node_t *y = NIL;
	if (z->left == NIL) {
		ia_binary_tree_transplant(T, z, z->right);
	} else if (z->right == NIL) {
		ia_binary_tree_transplant(T, z, z->left);
	} else {
		y = ia_binary_tree_minimum(z->right);
		if (y->p != z) {
			ia_binary_tree_transplant(T, y,y->right);
			y->right = z->right;
			z->right->p = y;
		}
		ia_binary_tree_transplant(T, z, y);
		y->left = z->left;
		y->left->p = y;
	}
}

test.c

#include <ia_include.h>

#define TEST_IASTACK_SIZE	10
#define TEST_IAQUEUE_SIZE	10
#define TEST_IABINARYTREE_NODES	20

void main()
{
	int i = 0;
	/*
	iastack_t test_stack;
	iaqueue_t test_queue;

	TRACE("=========Test iastack=========\n");

	iastack_init(&test_stack, TEST_IASTACK_SIZE);

	for (i = 0; i < (TEST_IASTACK_SIZE); ++i) {
		iastack_push(&test_stack, i);
	}

	for (i = 0; i < (TEST_IASTACK_SIZE); ++i) {
		TRACE("%d\t", iastack_pop(&test_stack));
	}
	TRACE("\n");

	iastack_free(&test_stack);

	TRACE("=========Test iaqueque=========\n");

	iaqueue_init(&test_queue, TEST_IAQUEUE_SIZE);

	for (i = 0; i < (8); ++i) {
		iaqueue_enqueue(&test_queue, i);
	}

	for (i = 0; i < (5); ++i) {
		TRACE("%d\t", iaqueue_dequeue(&test_queue));
	}
	TRACE("\n");

	for (i = 0; i < (7); ++i) {
		iaqueue_enqueue(&test_queue, i);
	}

	for (i = 0; i < (5); ++i) {
		TRACE("%d\t", iaqueue_dequeue(&test_queue));
	}
	TRACE("\n");

	iaqueue_free(&test_queue);
	*/
	FILE *f_out = NULL;
	binary_tree_t T;
	binary_tree_node_t t_nodes[TEST_IABINARYTREE_NODES];
	int nodes_v[TEST_IABINARYTREE_NODES] = 
		{ 5,  3,  4,  8,  1, 20, 33, 30, 34, 28,
		  8, 33, 11, 24, 11, 10, 12, 18, 22, 23 };

	T.root = NIL;
	memset(t_nodes, 0, sizeof(t_nodes));
	for (i = 0; i < sizeof(t_nodes)/sizeof(binary_tree_node_t); ++i) {
		t_nodes[i].key = nodes_v[i];
		ia_binary_tree_insert(&T, &t_nodes[i]);
	}

	f_out = fopen("out.txt", "w+");
	if (f_out == NULL) {
		TRACE("Fail to create file out.txt\nQuit!");
		goto l_exit;
	}

	ia_binary_tree_inorder_walk(T.root, NULL);

	
	//ia_binary_tree_inorder_walk(T.root, f_out);

	printf("\n\n");

	ia_binary_tree_delete(&T, &t_nodes[5]);
	ia_binary_tree_inorder_walk(T.root, NULL);
	ia_binary_tree_inorder_walk(T.root, f_out);

l_exit:
	if (f_out != NULL) {
		fclose(f_out);
	}
	printf("\n\n");
	system("pause");
}

2.输出





3. Tikz画图脚本

请参考:http://www.texample.net/tikz/examples/red-black-tree/

\tikzset{
  treenode/.style = {align=center, inner sep=0pt, text centered,
    font=\sffamily},
  arn_b/.style = {treenode, circle, white, font=\sffamily\bfseries, draw=black,
    fill=black, text width=2em},% arbre rouge noir, noeud noir
  arn_r/.style = {treenode, circle, red, draw=red, 
    text width=1.5em, very thick},% arbre rouge noir, noeud rouge
  arn_x/.style = {treenode, rectangle, draw=black,
    minimum width=0.5em, minimum height=0.5em},% arbre rouge noir, nil
  arn_n/.style = {treenode, circle, black, draw=black, 
    text width=2em, very thick}
}


\begin{document}
\begin{tikzpicture} [->,>=stealth',level/.style={sibling distance = 20cm/#1,
  level distance = 1.5cm}]

\node [arn_n] {root}
child {
node [arn_n] {5}
child {
node [arn_n] {3}
child {
node [arn_n] {1}
child {
node [arn_x] {}
}
child {
node [arn_x] {}
}
}
child {
node [arn_n] {4}
child {
node [arn_x] {}
}
child {
node [arn_x] {}
}
}
}
child {
node [arn_n] {8}
child {
node [arn_x] {}
}
child {
node [arn_n] {22}
child {
node [arn_n] {8}
child {
node [arn_x] {}
}
child {
node [arn_n] {11}
child {
node [arn_n] {10}
child {
node [arn_x] {}
}
child {
node [arn_x] {}
}
}
child {
node [arn_n] {11}
child {
node [arn_x] {}
}
child {
node [arn_n] {12}
child {
node [arn_x] {}
}
child {
node [arn_n] {18}
child {
node [arn_x] {}
}
child {
node [arn_x] {}
}
}
}
}
}
}
child {
node [arn_n] {33}
child {
node [arn_n] {30}
child {
node [arn_n] {28}
child {
node [arn_n] {24}
child {
node [arn_n] {23}
child {
node [arn_x] {}
}
child {
node [arn_x] {}
}
}
child {
node [arn_x] {}
}
}
child {
node [arn_x] {}
}
}
child {
node [arn_x] {}
}
}
child {
node [arn_n] {34}
child {
node [arn_n] {33}
child {
node [arn_x] {}
}
child {
node [arn_x] {}
}
}
child {
node [arn_x] {}
}
}
}
}
}
}

;


\end{tikzpicture}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值