静态查找的方法:顺序查找、对半查找、分块查找,C++代码实现

#include<iostream>
using namespace std;
typedef struct
{
	int r[100];
	int length;
}SSTable;
//顺序查找
int Search_Seq(SSTable &ST,int k)
{
	int i;
	ST.r[0]=k;//将0号单元作为哨兵,从而避免了每次查找都要判断i是否越界的问题
	i=ST.length;
	while(ST.r[i]!=k)
		i--;
	return i;//即如果查找失败,则返回0
}
//折半查找
//***************************************************
//折半查找要求静态查找表中的记录必须按关键字有序,
//故对一组无序数,要先进行排序,才能进行折半查找
//***************************************************
int Search_Bin(SSTable &ST,int k)
{
	int low,high,mid;
	low=1;
	high=ST.length;
	while(low<=high)
	{//low从1开始,即0号位置不用
		mid=(low+high)/2;
		if(k==ST.r[mid])
			return mid;
		else if(k<ST.r[mid])
			high=mid-1;
		else
			low=mid+1;
	}
	if(low>high)
		return 0;
}
//分块查找——索引查找
typedef struct
{
	int key;
	int stadr;
}IndexItem;
typedef struct
{
	IndexItem elem[51];
	int length;
}IndexTable;//索引表
int Search_Index(SSTable &ST,IndexTable &ID,int k)
{
	int low,high,mid;
	int p;//p用来保存查找的关键字所属的索引中的位置
	int s,t;//s,t分别用来保存查找的关键字所在块的起始和终点位置
	low=0;
	high=ID.length-1;
	while(low<=high && p<0)
	{//该循环是用对半查找的方法,对索引表进行查找,从而定位要查找的元素所在的块
		mid=(low+high)/2;
		if(k>ID.elem[mid-1].key && k<ID.elem[mid].key)
			p=mid;//判断关键字对应哪个索引位置,就是k比前一个值大,比后一个值小,
					//那个大的就是k对应的索引位置
		else
		{
			if(k<ID.elem[mid].key)
				high=mid-1;
			else if(k>ID.elem[mid].key)
				low=mid+1;
			else
				p=mid;
		}
	}
	s=ID.elem[p].stadr;
	if(p==ID.length-1)
		t=ST.length;//这里对p的判断很重要,p若是索引中最后一个位置,则t应该为ST的表长
	else
		t=ID.elem[p+1].stadr-1;
	while(k!=ST.r[s]&&s<=t)//这里在块里进行顺序查找
		s++;
	if(s>t)
		return 0;
	else
		return s;
}
//建立需要查找的表,和对半查找用的索引表
void CreateTable(SSTable &ST,IndexTable &ID,int n,int m)
{
	int i;
	cin>>ST.length;
	for(i=1;i<=n;i++)
		cin>>ST.r[i];
	cin>>ID.length;
	for(i=0;i<m;i++)
		cin>>ID.elem[i].key>>ID.elem[i].stadr;
}
void main()
{
	freopen("in.txt","r",stdin);
	//freopen("in1.txt","r",stdin);
	int i,j,k;
	SSTable ST;
	IndexTable ID;
	CreateTable(ST,ID,34,7);
	i=Search_Index(ST,ID,80);
	cout<<ST.r[i]<<endl;//分块查找
	/*cin>>ST.length;
	for(i=1;i<=10;i++)
		cin>>ST.r[i];
	j=Search_Bin(ST,30);//对半查找
	cout<<ST.r[j]<<endl;*/
	k=Search_Seq(ST,120);//顺序查找
	cout<<ST.r[k]<<endl;
}

静态查找本身不是很难,要说难的话,难点就在于分块查找。分块查找是先构建一个索引,该索引是有序的,如果在索引里用对半查找的话,肯定要能节省一些时间,而在每个块中的元素是无序的,所以只能用顺序查找,但是我在用对半查找方法写索引时,遇到点问题,对索引表的对半查找,不像单纯的对半查找一样,需要考虑比较多的情况,一开始我看书上的没看懂,又去网上搜一下,可是搜到的全都是用顺序查找方法查找的索引,我想既然索引表是有序的,如果不利用它这个特性,岂不是浪费?所以我就硬着头皮,去考虑对半查找的方法查找索引表的情况,程序中是我自己想出来的一个方法。书上的方法,虽然简单可行,但是让人理解起来可是非常不容易的。我觉得写程序追求的就是简单并且具有很好的可理解性,如果程序能符合我们大脑的正常思维过程,那是最好的了,易理解但执行起来又很快,但是个别除外(像一些特殊的算法)。不管怎么样,今天又写程序了,又克服了一个小难题,挺开心的!等你写程序,真正的深入到它以后,发现就会越来越喜欢它了,写程序也是一件蛮有意思的一件事情。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值