算法-查找-线性表的查找(顺序查找,二分查找,分块查找)

这里介绍几种基于线性表的查找方法:

  • 顺序查找
  • 二分查找
  • 分块查找

查找的定义是:给定一个值K,在含有n个结点的表中找出关键字等于给定值K的结点。若找到,则查找成功,返回该结点的信息或该结点在表中的位置;否则查找失败,返回相关的指示信息。

1、顺序查找

基本思想:从数据的一端开始查找,比较元素是否与查找元素相同,若有则查找成功,直到另一端结束。既适用于线性表的顺序存储结构,也适用于线性表的链式存储结构,但查找效率较低。

2、二分查找

也称为对半查找
基本思想:将待查找元素与序列中间值进行比较,若相等则找到,大于中值,则可以在右半边继续开始同样的查找工作,小于中值,则在左边;

  • 要求数据是有序的,向量作为存储结构,链表是无法实现二分查找的
  • 二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。

3、分块查找

也称索引顺序查找,性能介于顺序查找和二分查找

  • 基本思想:将数据进行分块,并用一个索引不表存储相关信息;将数据分成若干块,其中前一块的最大值不能大于后一块的最小值,用一个索引表存储每个块中的最大值和块的起始位置,块中的元素可以是无序的,但索引表必须是有序的。
  • 查找思路:先在索引表中查找,从而找到数据所在的块,然后在相应的块中的进行顺序查找,找到具体的位置。(基本思路就是先找到数据的范围,从而进行下一
    步的查找)

因为各查找方法应用的数据结构不尽相同,因此这里分开对之进行测试训练

顺序查找:

#include <iostream>
using namespace std;
const int N = 10;

int seqsearch(int (&a)[N], int k);

int main()
{
    int k, n = 10;
    int s[] = {5,6,2,3,9,8,4,1,7,0};
    k = seqsearch(s,n);
    cout << "元素所在位置:" << k << endl;
}

int seqsearch(int (&a)[N], int k)
{
    int i;
    for(i = 0; i<N; i++)
    {
        if(a[i] == k)
            return i;
    }
    return false;
    cout << "查找失败!";
}

二分查找,即利用迭代的方式不断进行查找

#include <iostream>
using namespace std;
const int N = 10;

int binsearch(int (&a)[10], int k);

int main()
{
    int k, n = 5;
    int s[] = {0,1,2,3,4,5,6,7,8,9};
    k = binsearch(s,n);
    if(k == N)
        cout << "查找失败" << endl;
    else
        cout << "元素所在位置:" << k << endl;
}

int binsearch(int (&a)[10], int k)
{
    int mid,left,right;
    left =0;
    right = N-1;
    while (left < right)
    {
        mid = (left + right) / 2;
        if(mid == k)
            return mid;
        else if(mid < k)
            left = mid + 1;
        else
            right = mid -1;
    }
    return N;  //false
}

分块查找,这里需要一个索引表,因此引用STL中的map来生成索引,这里介绍了map的建立及几种添加元素的方法,还有获取键值的两种方式。

#include <iostream>
#include <map> //利用STL中的map来建立索引表
using namespace std;
const int N = 15;

int blocksort(int (&s)[15], map<int,int> &map1, int k);

int main()
{
    int k, n = 5;
    int s[] = {1,3,2,0,4,9,6,5,8,7,12,11,10,13,14};  //每5个数为一块
    map<int,int>map1;     //建立索引表
    map1.insert(map<int,int>::value_type(0,4));    //三种map的插入方式,效果相同
    map1.insert(pair<int,int>(5,9));
    map1.insert(make_pair<int,int>(10,14));

    k = blocksort(s,map1,11);

    if(k == N)
        cout << "查找失败" << endl;
    else
        cout << "元素所在位置:" << k << endl;
}

int blocksort(int (&s)[15], map<int,int> &map1, int k)
{
    int index, blocksize = 5;        
    int i = 0;
    //int a[3]; //获取map索引值的两种方法
    //way 1
    //a[0] = map1.at(0);
    //a[1] = map1.at(5);
    //a[2] = map1.at(10);
    //way 2 迭代方式
    //map<int,int>::iterator it;
    //for(i,it = map1.begin(); it != map1.end(); ++it,++i)
    // a[i] = it->second;


    map<int,int>::iterator it;
    for(i,it = map1.begin(); it != map1.end(); ++it,++i){
        if(k<=it->second){
            index = it->first;
            break;
        }
    }

    for(i = index; i<index + blocksize; i++)
    {
        if(s[i] == k)
            return i;
    }
    return N;  //false
}
    原文作者:查找算法
    原文地址: https://blog.csdn.net/ahafg/article/details/49757751
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞