算法导论代码 第12章 二叉查找树

12章 二叉查找树

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct binary_search_tree_type *tree;
struct tree_node {
	void *key;
	struct tree_node *parent;
	struct tree_node *left;
	struct tree_node *right;
};
struct binary_search_tree_type {
	int (*comp) (const void *, const void *);
	struct tree_node *root;
};
void tree_node_ini(struct tree_node *p, void *key)
{
	p->key = key;
	p->parent = NULL;
	p->left = NULL;
	p->right = NULL;
}

tree tree_create(int (*comp) (const void *, const void *))
{
	tree t = malloc(sizeof(struct binary_search_tree_type));
	t->comp = comp;
	t->root = NULL;
	return t;
}

void tree_delete_node(tree t, struct tree_node *x, void (*free_key) (void *))
{
	if (x != NULL) {
		tree_delete_node(t, x->left, free_key);
		tree_delete_node(t, x->right, free_key);
		free_key(x->key);
		free(x);
	}
}

void tree_destroy(tree t, void (*free_key) (void *))
{
	tree_delete_node(t, t->root, free_key);
	free(t);
}

void tree_inorder_tree_walk(struct tree_node *x, void (*handle) (const void *))
{
	if (x != NULL) {
		tree_inorder_tree_walk(x->left, handle);
		handle(x->key);
		tree_inorder_tree_walk(x->right, handle);
	}
}

struct tree_node *tree_search(tree t, struct tree_node *x, void *key)
{
	if (x == NULL || t->comp(key, x->key) == 0) {
		return x;
	}
	if (t->comp(key, x->key) < 0) {
		return tree_search(t, x->left, key);
	} else {
		return tree_search(t, x->right, key);
	}
}

struct tree_node *tree_search_iterative(tree t, struct tree_node *x, void *key)
{
	while (x != NULL && t->comp(key, x->key) != 0) {
		if (t->comp(key, x->key) < 0) {
			x = x->left;
		} else {
			x = x->right;
		}
	}
	return x;
}

struct tree_node *tree_minimum(struct tree_node *x)
{
	while (x != NULL && x->left != NULL) {
		x = x->left;
	}
	return x;
}

struct tree_node *tree_maximum(struct tree_node *x)
{
	while (x != NULL && x->right != NULL) {
		x = x->right;
	}
	return x;
}

struct tree_node *tree_successor(struct tree_node *x)
{
	if (x->right != NULL) {
		return tree_minimum(x->right);
	}
	struct tree_node *y = x->parent;
	while (y != NULL && x == y->right) {
		x = y;
		y = y->parent;
	}
	return y;
}

struct tree_node *tree_predecessor(struct tree_node *x)
{
	if (x->left != NULL) {
		return tree_maximum(x->left);
	}
	struct tree_node *y = x->parent;
	while (y != NULL && x == y->left) {
		x = y;
		y = y->parent;
	}
	return y;
}

void tree_insert(tree t, struct tree_node *z)
{
	struct tree_node *y = NULL;
	struct tree_node *x = t->root;
	while (x != NULL) {
		y = x;
		if (t->comp(z->key, x->key) < 0) {
			x = x->left;
		} else {
			x = x->right;
		}
	}
	z->parent = y;
	if (y == NULL) {
		t->root = z;
	} else {
		if (t->comp(z->key, y->key) < 0) {
			y->left = z;
		} else {
			y->right = z;
		}
	}
}

void swap(void *a, void *b, size_t elem_size)
{
	if (a == NULL || b == NULL || a == b)
		return;
	char temp[elem_size];	/*变长数组 */
	memcpy(temp, a, elem_size);
	memcpy(a, b, elem_size);
	memcpy(b, temp, elem_size);
}

struct tree_node *tree_delete(tree t, struct tree_node *z)
{
	struct tree_node *y;
	struct tree_node *x;
	if (z->left == NULL || z->right == NULL) {
		y = z;
	} else {
		y = tree_successor(z);
	}
	if (y->left != NULL) {
		x = y->left;
	} else {
		x = y->right;
	}
	if (x != NULL) {
		x->parent = y->parent;
	}
	if (y->parent == NULL) {
		t->root = x;
	} else {
		if (y == y->parent->left) {
			y->parent->left = x;
		} else {
			y->parent->right = x;
		}
	}
	if (y != z) {
		/*要删除的结点y是z的后继,交换z和y结点的内容 */
		swap(&z->key, &y->key, sizeof(void *));
	}
	return y;
}

int cmp_int(const void *p1, const void *p2)
{
	const int *pa = p1;
	const int *pb = p2;
	if (*pa < *pb)
		return -1;
	if (*pa == *pb)
		return 0;
	return 1;
}
void print_key(const void *key)
{
	const int *p = key;
	printf("%d ", *p);
}

int main()
{
	tree t = tree_create(cmp_int);
	for (int i = 0; i < 10; i++) {
		struct tree_node *node = malloc(sizeof(struct tree_node));
		int *ip = malloc(sizeof(int));
		*ip = i;
		tree_node_ini(node, ip);
		tree_insert(t, node);
	}
	printf("中序遍历结果:\n");
	tree_inorder_tree_walk(t->root, print_key);
	printf("\n");
	struct tree_node *max = tree_maximum(t->root);
	printf("max:%d\n", *(int *)max->key);
	struct tree_node *min = tree_minimum(t->root);
	printf("min:%d\n", *(int *)min->key);
	struct tree_node *success = tree_successor(min);
	printf("%d的后继:%d\n", *(int *)min->key, *(int *)success->key);
	struct tree_node *predecessor = tree_predecessor(max);
	printf("%d的前趋:%d\n", *(int *)max->key, *(int *)predecessor->key);
	int k = 0;
	struct tree_node *result = tree_search(t, t->root, &k);
	printf("查找关键字:%d的结果:%s\n", k,
	       result != NULL ? "成功" : "失败");
	struct tree_node *del_node = tree_delete(t, result);
	free(del_node->key);
	free(del_node);
	result = tree_search(t, t->root, &k);
	printf("删除关键字:%d的结果:%s\n", k,
	       result == NULL ? "成功" : "失败");
	printf("中序遍历结果:\n");
	tree_inorder_tree_walk(t->root, print_key);
	printf("\n");
	tree_destroy(t, free);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值