二叉排序树_C++实现

1.二叉排序树的定义
 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
③左、右子树本身又各是一棵二叉排序树。
 上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。

2.二叉排序树的性质
   按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。

3.二叉排序树的插入
   在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。  
   插入过程:
   若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;  
   当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。

//二叉查找树
typedef struct BinarySearchTreeNode {
	int value;
	struct BinarySearchTreeNode *left;
	struct BinarySearchTreeNode *right;
}BSTNode, *BST;

//插入操作
void insertBST(BST &root, int value) {
	BST p = root, parent = NULL;
	if(root == NULL) {
		root = new BSTNode();
		root->value = value;
		root->left = NULL;
		root->right = NULL;
	}
	else {
		while(p != NULL) {
			parent = p;
			if(p->value == value)
				return;
			else if(p->value > value)
				p = p->left;
			else
				p = p->right;
		}
		p = new BSTNode();
		p->value = value;
		p->left = NULL;
		p->right = NULL;
		if(parent->value > value)
			parent->left = p;
		else
			parent->right = p;
	}
}

4.二叉排序树的查找
   假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:
 ① 置初值: q = root ;
 ② 如果 K = q -> key ,则查找成功,算法结束;
 ③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q ,转步骤②;否则,查找失败,结束算法;

 ④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q ,转步骤②;否则,查找失败,算法结束。

//查找操作
BST searchBST(BST &root, int value) {
	if(root == NULL) 
		return NULL;
	if(root->value == value)
		return root;
	else if(root->value > value)
		return searchBST(root->left, value);
	else
		return searchBST(root->right, value);
}

5.二叉排序树的删除
   假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论:  
   ⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。  
   ⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR 成为其双亲结点的左子树即可。  

   ⑶ 若结点*p的左、右子树均非空,先找到*p的中序前趋(或后继)结点*s(注意*s是*p的左子树中的最右下的结点,它的右链域为空),然后有两种做法:① 令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。② 以*p的中序前趋结点*s代替*p(即把*s的数据复制到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。

//删除操作,删除成功返回ture,删除失败返回false
bool deleteBST(BST &root, int value) {
	BST p = root, parent = NULL;
	while(p != NULL) {
		if(p->value == value)
			break;
		else if(p->value > value) {
			parent = p;
			p = p->left;
		}
		else {
			parent = p;
			p = p->right;
		}
	}
	if(p == NULL)
		return false;
	if(p->left == NULL || p->right == NULL) {
		 if(parent == NULL) {
			 root = NULL;
		 }
		 else {
			if(parent->left == p) {
				parent->left = (p->left == NULL) ? p->right : p->left;
			}
			else {
				parent->right = (p->left == NULL) ? p->right : p->left;
			}
		 }
		 delete p;
	}
	else {
		BST pre = p, mid = p->left;
		while(mid->right != NULL) {
			pre = mid;
			mid = mid->right;
		}
		p->value = mid->value;
		if(pre->left == p) {
			pre->left = mid->left;
		}
		else {
			pre->right = mid->left;
		}
		delete mid;
	}
	return true;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值