二叉查找树

#include <stdio.h>
#include <stdlib.h>

struct node
{
	int data;
	struct node *parent;
	struct node *left;
	struct node *right;
};

struct tree
{
	struct node *root;
};

/* 创建一个结点 */
struct node *node_alloc(int val)
{
	struct node *ret = (struct node *) malloc(sizeof(struct node));
	ret->data        = val;
	ret->parent      = NULL;
	ret->left        = NULL;
	ret->right       = NULL;
	return ret;
}

/* 销毁一个结点 */
void node_dealloc(struct node *n)
{
	n->parent = NULL;
	n->left   = NULL;
	n->right  = NULL;
	free(n);
}

/* 销毁整个子树 */
void node_destroy(struct node *n)
{
	if (n->left != NULL)
	{
		node_destroy(n->left);
	}
	if (n->right != NULL)
	{
		node_destroy(n->right);
	}
	node_dealloc(n);
}

/* 返回子树中最小的元素 */
struct node *node_minimum(struct node *n)
{
	while (n->left != NULL)
	{
		n = n->left;
	}
	return n;
}

/* 返回子树中最大的元素 */
struct node *node_maximum(struct node *n)
{
	while (n->right != NULL)
	{
		n = n->right;
	}
	return n;
}

/* 查找结点在中序遍历序列中的前趋 */
struct node *node_predecessor(struct node *n)
{
	struct node *ret;

	if (n->left != NULL)
	{
		return node_maximum(n->left);
	}
	else
	{
		ret = n->parent;
		while (ret != NULL && ret->left == n)
		{
			n   = ret;
			ret = n->parent;
		}
	}
	return ret;
}

/* 查找结点在中序遍历序列中的后继 */
struct node *node_successor(struct node *n)
{
	struct node *ret;

	if (n->right != NULL)
	{
		return node_minimum(n->right);
	}
	else
	{
		ret = n->parent;
		while (ret != NULL && ret->right == n)
		{
			n   = ret;
			ret = n->parent;
		}
	}
	return ret;
}

/* 输出子树的中序遍历序列 */
void node_inorder_traversal(struct node *n)
{
	if (n->left != NULL)
	{
		node_inorder_traversal(n->left);
	}
	printf("%d ", n->data);
	if (n->right != NULL)
	{
		node_inorder_traversal(n->right);
	}
}

/* 插入 */
void tree_insert(struct tree *t, int val)
{
	struct node *parent = NULL;
	struct node *child  = t->root;

	/* 查找应该插入的位置parent */
	while (child != NULL)
	{
		parent = child;
		if (val < child->data)
		{
			child = child->left;
		}
		else
		{
			child = child->right;
		}
	}

	/* 如果parent == NULL说明为空树 */
	if (parent == NULL)
	{
		t->root = node_alloc(val);
	}
	else
	{
		child = node_alloc(val);
		child->parent = parent;
		if (val < parent->data)
		{
			parent->left = child;
		}
		else
		{
			parent->right = child;
		}
	}
}

/* 删除 */
void tree_erase(struct tree *t, struct node *n)
{
	struct node *del;
	struct node *child;

	if (n == NULL)
	{
		return;
	}

	/* 查找应该删除的结点del,del最多只有一个子结点 */
	if (n->left == NULL || n->right == NULL)
	{
		del = n;
	}
	else
	{
		del = node_successor(n);
		/* 若待删除的结点不为n,将待删除结点的数据赋给n */
		n->data = del->data;
	}

	/* 调整子节点的父结点指针 */
	if (del->left != NULL)
	{
		child = del->left;
	}
	else
	{
		child = del->right;
	}
	if (child != NULL)
	{
		child->parent = del->parent;
	}

	/* 若父结点为NULL,说明待删除的结点为树的根结点,此时需要重新调整树的根结点 */
	if (del->parent == NULL)
	{
		t->root = child;
	}
	/* 调整父结点的子结点指针 */
	else if (del->parent->left == del)
	{
		del->parent->left = child;
	}
	else
	{
		del->parent->right = child;
	}

	/* 销毁结点 */
	node_dealloc(del);
}

/* 查找,返回中序遍历序列中第一个匹配的 */
struct node *tree_search(struct tree *t, int val)
{
	struct node *ret = t->root;

	while (ret != NULL)
	{
		if (val == ret->data)
		{
			break;
		}
		else if (val < ret->data)
		{
			ret = ret->left;
		}
		else
		{
			ret = ret->right;
		}
	}
	return ret;
}

/* 树结构初始化 */
void tree_init(struct tree *t)
{
	t->root = NULL;
}

/* 销毁整棵树 */
void tree_destroy(struct tree *t)
{
	if (t->root != NULL)
	{
		node_destroy(t->root);
		t->root = NULL;
	}
}

/* 输出树的中序遍历序列 */
void tree_inorder_traversal(struct tree *t)
{
	if (t->root != NULL)
	{
		node_inorder_traversal(t->root);
		printf("\n");
	}
}

int main(void)
{
	struct tree t;
	struct node *n;

	tree_init(&t);

	tree_insert(&t, 1);
	tree_insert(&t, 2);
	tree_insert(&t, 3);
	tree_insert(&t, 4);
	tree_insert(&t, 5);
	tree_inorder_traversal(&t);

	n = tree_search(&t, 1);
	tree_erase(&t, n);
	tree_inorder_traversal(&t);
	n = tree_search(&t, 3);
	tree_erase(&t, n);
	tree_inorder_traversal(&t);
	n = tree_search(&t, 4);
	tree_erase(&t, n);
	tree_inorder_traversal(&t);

	tree_destroy(&t);

	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值