【模板】二叉排序树

二叉排序树的定义:

(1)对于任何一个结点,如果左子树不空,其左子树的所有节点的关键字均小于它的根节点的关键字。

(2)对于任何一个结点,如果右子树不空,其右子树的所有节点的关键字均大于它的根节点的关键字。

(3)它的左子树、右子树都是二叉排序树。

二叉排序树的特性:

其中序遍历将得到的序列是从小到大的序列。

二叉排序树的查找:

只要关键字不相等,且当前节点不为空树就继续搜索。当小于当前节点关键字时,搜索左子树,当大于时,搜索右子树。(下面的代码没有对不存在该关键字的情况处理,所以此时输出的实际上是其插入后的双亲结点)

二叉排序树的插入:

 原理和上述类似,区别在于其采用递归。当搜索到空节点时,说明找到了插入位置,此时要动态分配内存建立新节点并插入。注意要返回当前的根节点,否则之后的调用会错误(仍然是空树)。

下面代码记录了插入结点时的双亲结点和查找结点时的双亲结点。

#include<iostream>
#include<cstring>
#include<cstdlib> 
using namespace std;
struct Node{
	int data;
	Node* left;
	Node* right;
}; 
Node* Search(Node* T,int &key,int &f){
	while(T!=NULL&&key!=T->data) 
	{
		if(key<T->data)
		{
			f = T->data;//将当前的结点关键字记录下来 
			T=T->left;//搜索左子树 
		}
		else
		{
			f = T->data;//将当前的结点关键字记录下来
			T=T->right;//搜索右子树 
		}
	}
	return T;//返回双亲节点 
} 
Node* Insert(Node* T,int newKey,int &f){
//根节点、新节点的关键字、引用f(记录加入结点的双亲结点,全局变量) 
//引用f是为了在整个递归期间只有一个 
	if(T==NULL){
		T=(Node*)malloc(sizeof(Node));//动态分配结点内存 
		T->data = newKey;
		T->left = T->right = NULL;
	}
	else if(newKey<T->data){//小于关键字 
		f = T->data;//接下来以左孩子为根插入,记录当前双亲结点 
		T->left = Insert(T->left,newKey,f);
	}
	else{
		f = T->data;//接下来以有孩子为根插入,记录当前双亲结点 
		T->right = Insert(T->right,newKey,f);
	}
	return T;//返回当前根结点
}
int main(void){
	int n;
	while(scanf("%d",&n)!=EOF){
		Node* root=NULL;//根节点 
		int newKey;
		for(int i=0;i<n;i++){
			int f=-1;
			scanf("%d",&newKey);
			root = Insert(root,newKey,f);//必须返回根节点,不然出下次插入时根节点还是NULL 
			printf("%d\n",f);
		}
		int k;
		scanf("%d",&k);//查找k次 
		int searchKey;
		for(int i=0;i<k;i++){
			int f=-1;
			scanf("%d",&searchKey);
			Search(root,searchKey,f);
			printf("%d\n",f);
		}
	}
	return 0; 
} 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值