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