二叉排序树

1、二叉排序树特征

二叉排序树又称二叉搜索树,满足下列特征:

  • 若根节点的左子树非空,则左子树上的所有节点关键字均小于根节点关键字;
  • 若根节点的右子树非空,则右子树上的所有节点关键字均大于根节点关键字;
  • 根节点的左、右子树本身又是二叉排序树。
    在此,讨论节点为整型的二叉排序树。
typedef struct bstnode {
	int data;
	struct bstnode *left;
	struct bstnode *right;
}BSTNode;	//节点结构

2、插入

bool InsertBST(BSTNode *&bt, int k) {
	//注意bt为引用类型
	if (bt == nullptr) {
		bt = (BSTNode*)malloc(sizeof(BSTNode));
		bt->data = k; bt->left = nullptr; bt->right = nullptr;
		return true;
	}
	else if (bt->data == k)
		return false;
	else if (bt->data > k)
		return InsertBST(bt->left, k);
	else
		return InsertBST(bt->right, k);
}

3、创建

BSTNode* CreateBSTree(int A[], int n) {
	BSTNode *bt = nullptr;
	for (int i = 0; i < n; ++i)
		InsertBST(bt, A[i]);
	return bt;
}

4、查找

BSTNode *SearchBST(BSTNode *bt, int k) {
	if (bt == nullptr)
		return nullptr;
	if (bt->data == k)
		return bt;
	else if (bt->data < k)
		return SearchBST(bt->right, k);
	else
		return SearchBST(bt->left, k);
}

5、删除节点

/*
删除节点过程分以下几种情况
1、若p是叶子节点,直接删除
2、若p节点只有左子树而无右子树,可用其左孩子节点代替p
3、若p节点只有右子树而无左子树,将其右孩子节点替代p
4、若p节点同时有左右子树,选择左子树中最大的节点用其替代p,然后删除左子树最大的节点(第2种情况)
*/
void Delete(BSTNode *&bt);
void Delete1(BSTNode *&bt, BSTNode *&b);
bool DeleteBST(BSTNode *&bt, int k) {
	if (bt == nullptr)
		return false;
	else {
		if (bt->data < k)
			DeleteBST(bt->right, k);
		else if (bt->data > k)
			DeleteBST(bt->left, k);	//递归查找节点
		else {
			Delete(bt);
			return true;
		}
	}
}
void Delete(BSTNode *&bt) {
	BSTNode *p;
	if (bt->left == nullptr) {//左孩子为空
		p = bt;
		bt = bt->right;
		free(p);
	}
	else if (bt->right == nullptr) {//右孩子为空
		p = bt;
		bt = bt->left;
		free(p);
	}
	else {
		Delete1(bt,bt->left);//左右均不空
	}
}
void Delete1(BSTNode *&bt, BSTNode *&b) {
	BSTNode *p;
	if (b->right != nullptr)
		Delete1(bt, b->right);	//找左孩子节点中最大的
	else {
		bt->data = b->data;
		p = b;
		b = b->left;	//由于参数是传引用,因此这里代表原来指向b的父节点现在指向b的左孩子
		free(p);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值