学习算法第三篇:查找算法

来源:互联网 发布:股票交易助手小软件 编辑:程序博客网 时间:2024/05/05 19:51

1.顺序查找

顺序查找主要是针对顺序文件运行的查找指定关键记录的算法,根据物理存储地址是否相连又分为连续顺序文件和链接顺序文件。这里讲的是连续顺序文件:

算法的想法十分直观简单

1)从文件的第一个记录开始,将每个记录的关键字与给定的关键字比较

2)如果找到某个记录的关键字等于key,则查找成功,返回位置;如果所有记录都进行了比较,仍未找到与k相等的记录,则给出0,表示查找失败。

template<typename datatype>seqsearch(datatype key[],int n,datatype k)
{
for(int i=1;i<n;i++)
{
if(key[i]==k)
{
return i;
}
}
return 0;
}

2.二分查找

如果记录的关键字是有序排列,我们采用比顺序查找更有效的方法来查找指定的关键字k,即二分查找。

查找算法的步骤如下:

例如有序数据集(26,31,55,43,56,78,121,123,456)我们查找121,那么

(1)找出数据集中的中间位置的记录,本数据集共有9个数据,编号是0~8,设置指针lowhigh分别指向0号位置和8号位置,中间位置为mid=(low+high)/2,所以121先与56比较,大于56,我们将修正为(low+high)/2+1

(2)对数据集的后半部分进行上述过程,mid=(low+high)/2=6,第六个数上刚好为121,查找结束,返回6

template<typename datatype>int  binsearch(datatype key[],int n,datatype k)
{
int low=0,high=n-1;
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(k==key[mid])
return mid;
else if(k>key[mid])
low=mid+1;
else 
high=mid-1;
}
reurn NULL;

3.二叉树查找

二叉树查找是一种具有良好排序和查找性能的二叉树结构,如果二叉树的根节点的左子树不为空,则左子树中的所有结点值均小于根节点,如果右子树不为空,则右子树的值都大于根节点。

template<typename datatype> sbtnode<datatype>* sbt<datatype>::search(datatype k)
{
sbtnode<datatype>*node=root;
while(node!=NULL)
{
if(k<node->data)
node=node->lchild;
else if(k>node->data)
node=node->rchild;
else 
break;
}
return node;
}


4.分块查找

分块查找又称为索引分块文件查找,是一种在非稠密索引分块文件上执行的查找算法。

(1)先搜索引表,利用顺序查找或者二分查找算法,确定待查记录关键字k,属于哪儿个块,在索引表一般存这个块中最大或最小值。

(2)根据索引表中块首记录的地址找到主表中块的起始地址,利用顺序查找方法查找k,如果找到则返回记录地址,如果没找到则返回NULL

typedef struct
{
int key;
int ip;//记录每块中的最大值//
}Index;
typedef struct
{
int key;
float info;
}datalist;
int blocksearch(datalist *data,int n,Index*index,int m,int k)
{
int i=0;
int ip;
while(k<index[i].key&&i<m)
       i++;
ip=index[i].ip;
int endip=ip+n;//n为块中的元素个数//
while(k!=data[ip].key&&ip<endip)
ip++;
if(ip==index[i+1].ip)
return NULL;
return ip;
}

索引表

25

58

88

16

14

23

25

58

4

35

34

88

45

78

50

数据块


5.哈希查找

哈希查找(通过计算数据元素的存储地址进行查找的)

(1)用给定的哈希函数来构造哈希表,然后将所有的数据用哈希函数计算后重新以一种不同的值来记录它的存储位置

(2)根据选择的冲突处理方法解决地址冲突,一般有开放定址法、链地址法。

(3)在哈希表的建立基础上执行哈希查找

哈希函数的构造的方法经常有以下一些:

(1)取余法:key=value%size;

(2)直接定址:key=value+c;

(3)折叠法:value=213456,以2位单位,先将各个位上的数相加21+34+56=111,然后去掉1,取key=11

tempalte<typename datatype>int hashtable<datatype>::search(datatype value)
{
int p=hash(value);
if(elements[p]==value)
return p;
int rp=(p+1)%maxsize;
while(rp!=p)//循环使用线性探测法解决冲突//
{
if(elements[rp]==value)
return rp;
if(elements[rp]==NULL)//找到空白地址//
break;
rp=(rp+1)%maxsize;
}
if(rp==p)
return -2;//没找到//
else
{
elements[rp]=value;//在空白地址上插入此元素//
return rp;
}
}





0 0
原创粉丝点击