二叉排序树算法

结点的删除有点错误??以后再改正


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

#define ARRAYLEN 10
int source[] = {54, 90, 6, 69, 12, 37, 92, 28, 65, 83};

typedef struct bst
{
	int data;
	struct bst *left;
	struct bst *right;
}BSTree;
//BinarySortTree
//将一个数插入到二叉排序树中
void InsertBST(BSTree *t, int key)
{
	BSTree *p, *parent, *head;
	
	p = (BSTree *)malloc(sizeof(BSTree *));

	if (!p)
	{
		printf("error\n");
		exit(0);
	}

	p->data = key;
	p->left = NULL;
	p->right = NULL;
	head = t;

	while(head)
	{
		parent = head;
		if (key < head->data)
			head = head->left;
		else
			head = head->right;
	}

	if (key < parent->data)
		parent->left = p;
	else
		parent->right = p;
}

//创建一个二叉排序树
void CreateBST(BSTree *t, int data[], int n)
{
	int i;
	t->data = data[0];
	t->left = t->right = NULL;
	for (i = 1; i < n; i++)
		InsertBST(t, data[i]);
}

//中序遍历
void BST_LDR(BSTree *t)
{
	if (t)
	{
		BST_LDR(t->left);
		printf("%d ", t->data);
		BST_LDR(t->right);
	}
	return;
}
//查找结点
BSTree *SearchBST(BSTree *t, int key)
{
	if (!t || t->data == key)
		return t;
	else if (key > t->data)
		return (SearchBST(t->right, key));
	else
		return (SearchBST(t->left, key));
}


//删除结点
/*
	三种情况:
	1、若删除的结点是二叉排序树的叶结点,即t->left和t->right都为空。这时只需要修改t结点的父结点的指针,
	并释放t结点占用的内存即可。
	2、若t结点只有一个子树(即t->left或t->right为空),这时只需要修改t结点的父结点,使其子结点的值为t->left,t->right
	3、若t结点有两个子树(即t->left和t->right都不为空),这时,只需在被删除结点的右子树中查找,找到最左侧的叶结点,
	将该叶结点的值移到被删除结点即可。
*/

void BST_Delete(BSTree *t, int key)
{
	BSTree *p, *parent, *l, *ll;
	int child = 0;//0表示左子树,1表示右子树
	if (!t) return;

	p = t;
	while(p)
	{
		if (p->data == key)
		{			
			if (!p->left && !p->right)//叶结点
			{
				if (p == t)
				{
					free(p);
				}
				else if (child == 0)
				{
					parent->left = NULL;
					free(p);
				}
				else
				{
					parent->right = NULL;
					free(p);
				}
			}		
			else if (!p->left)	//左子树为空,右子树不为空
			{
				if (child == 0)//是父结点的左子树
					parent->left = p->right;
				else
					parent->right = p->left;
				free(p);
			}			
			else//左右子树都不为空
			{
				ll = p;//保存左子树的父结点
				l = p->right;//从当前结点的右子树进行查找
				while (l->left)
				{
					ll = l;
					l = l->left;//查找左子树					
				}
				p->data = l->data;
				ll->left = NULL;
				free(l->right);//这里可能有问题?
			}
			p = NULL;		
		}
		else if (key < p->data)
		{
			child = 0;
			parent = p;
			p = p->left;
		}
		else
		{
			child = 1;
			parent = p;
			p = p->right;
		}
	}
}
int main()
{
	int key, i;
	BSTree bst, *pos;

	printf("原来的数据为:\n");
	for (i = 0; i < ARRAYLEN; i++)
		printf("%d ", source[i]);
	CreateBST(&bst, source, ARRAYLEN);
	printf("\n遍历二叉排序树结果:\n");
	BST_LDR(&bst);
	printf("\n输入要查找的数值:");
	scanf("%d", &key);
	pos = SearchBST(&bst, key);
	if (pos)
		printf("查找成功,结点%d的地址为%x\n", pos->data, pos);
	else
		printf("查找失败!\n");

	//printf("输入要删除的结点:");
	//scanf("%d", &key);
	//BST_Delete(&bst, key);
	//printf("\n删除结点%d之后遍历二叉排序树结果:\n", key);
	//BST_LDR(&bst);

	getchar();
	getchar();
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值