数据结构查找算法之二叉查找树

关于二叉查找树,介绍肯定是很多的,这里我列举的下面的代码和思想,是按照二叉查找树,但是没有使用二叉树的数据结构,而是按照数组索引建立逻辑上的二叉树结构,并使用二叉树的递归方式查找给定的值,并在注释中对不同的情况提出一点自己的看法,创建树的过程参考堆排序的思想,并且在结构上大致相同,所以需要注意的地方也基本上相同,前面介绍了推排序需要注意的地方,这里有几个地方需要说明的是,里面有一段二分查找的函数代码,只是前面使用过,放在这里也是为了和后面做个对比,并且该函数和我们一般使用的二分查找算法略有不同,代码注释中提到了,下面就直接将详细的代码和注释贴出来。
#include <iostream>
#include <assert.h>
#include <string>
#include <algorithm>

using namespace std;
/*
主要是这几种基本的算法:	1 顺序查找,
						2 二分查找
						3 二叉查找树,基础是一颗排序树,创建树的方法可以参考二叉堆,
						查找按递归即可,至于插入和删除只要看是影响前面还是后面的节
						点,调整即可,参考二叉堆
						4 
*/
/*
	二分查找,是不分顺序的查找算法,在基本有序的情况下,
	使用有序的二分查找算法效率确实高很多
*/
template <typename T>
int binarySearch(T array[],int s,int e,T &t){
	assert(e >= s);
	if(s == e){
		if(array[s] !=t)
			return -1;
		return s;
	}
	int m=(s+e)>>1;
	int result = binarySearch(array,s,m,t);
	if(result != -1) return result;
	return binarySearch(array,m+1,e,t);
}

/* 
	下面使用二叉查找树,有几个基本的过程:1 创建二叉查找树,
	按照创建推的方法创建,2 调整二叉查找树,3 遍历树
*/
//二叉树的数据结构
// template <typename T>
// struct BinaryNode{
// 	T t;
// 	BinaryNode *leftNode;
// 	BinaryNode *rightNode;
// 	
// };
/*
	这里我想针对不同的情况应该有两种解决方案:	1 第一种是已经存在二叉树,只需要遍历查找
											2 第二种就是需要自己创建,然后查找,
	这里我选择实现第二种解决方案,但是不使用二叉树的数据结构参考推的创建方法,用位置绑定
	节点之间的关系。
*/
//这个函数还真是蛋疼,虽然很简单,但是很头疼
template <typename T>
void exchange(T &t1,T &t2, T &t3){
	if(t2 < t1)
		swap(t1,t2);
	if(t3 <t1)
		swap(t1,t3);
	if(t3 < t2)
		swap(t2,t3);
//	T mintemp = t1 < t2 ? t1: t2;
//	T maxtemp = t1 < t2 ? t2: t1;

//	t temp3 = maxtemp < t3			//还是会有问题
}


template <typename T>			//i不能为零,数组的起点需要为1
void AdjustBinarytree(T array[],int i,int size){
	int l = i<<1;
	int r = (i<<1) +1;	
	if(l <= size ){
		if( r <= size){
			exchange(array[l],array[i],array[r]);
			AdjustBinarytree(array,l,size);			//左右两边都需要调整
			AdjustBinarytree(array,r,size);
		}
		else{
			//array[i] = array[i] < array[l] ? array[l]:array[i];	//array[i]取大的
			if(array[i] < array[l])	swap(array[i],array[l]);
			AdjustBinarytree(array,l,size);
		}	
	}
}

template <typename T>
void buildBinarytree(T array[],int n){
	for(int i=n/2;i>= 1 ;i--)
		AdjustBinarytree(array,i,n-1);
}


/*
	还存在一个问题, 就是找到了原来的节点之后,因为调整过
	原来的节点,所以输出的对应的位置和原来输入的序列的位置
	不同,这里可以从数据结构上变动,
	
	struct {
	T t;
	size_t location;	//保存输入时位置信息
	};
	最后按照对应的位置即可找到输入时的序列的位置
*/
template <typename T>		//i表示当前查询到的节点
int binaryTreeSearch(T array[],int i,int size,T &t){
	if(i > size )	return -1;
	if(t == array[i])	return i;
	if(t < array[i])	return binaryTreeSearch(array,i<<1,size,t);
	return binaryTreeSearch(array,((i<<1)+1),size,t);
}

// template <typename T>					//size可以不用,直接用后面的节点
// void AdjustBinaryTree(BinaryNode *CurrentNode){
// 	if(CurrentNode == NULL)	return ;
// 	T temp = CurrentNode->t;
// 	T ltemp,rtemp;
// 	BinaryNode * tempCurrentNode = CurrentNode;
// 	if(CurrentNode ->leftNode != NULL){
// 		ltemp = CurrentNode ->leftNode ->t;
// 		if(ltemp )
// 	}if()
//  
// }


int main(){
	int n;
	string array[20];
//	int array[20];
	while(cin>>n){
		for(int i=0;i<n;i++)
			cin>>array[i];

		string  str;
		cin >> str;
		buildBinarytree(array,n);
		//int local = binarySearch(array,0,n-1,str);
		int local = binaryTreeSearch(array,1,n,str);
		cout <<local <<endl;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值