基于线性表的查找法

来源:互联网 发布:知乎 未解之谜 编辑:程序博客网 时间:2024/05/29 08:26

顺序结构数据类型的定义

#define MAXSIZE 10typedef struct{    int key;    //...列表中的其他信息}Record;typedef struct{    int length;    Record data[MAXSIZE + 1]; //data[0]为工作单元,存放待查找的数据,防止下标访问过界}RecordList;

顺序查找
算法思想:在表的一端设置一个称为“监视哨”的附加单元,存放要查找元素的关键字。从表的另一端开始查找,如果在“监视哨”找到要查找元素的关键字,返回失败信息,否则返回相应下标。
性能分析:假设列表长度为n,那么查找到第i个数据元素时需进行n-i+1次比较。
ASL = 1/n∑(n-i+1) = (n+1)/2

折半查找
算法思想:首先,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。
重复以上步骤,直到找到满足条件的结果为止,若找不到,则返回失败。
要求:
1.必须采用顺序存储结构;
2.必须按关键字大小有序排列。
图示分析:
这里写图片描述
程序示例:

#include <stdio.h>#define MAXSIZE 10typedef struct{    int key;    //...列表中的其他信息}Record;typedef struct{    int length;    Record data[MAXSIZE + 1]; //data[0]为工作单元,存放待查找的数据,防止下标访问过界}RecordList;//顺序查找int SeqSearch(RecordList RL, int key){    int i = RL.length;     //初始化为顺序表长度,从后往前查找    RL.data[0].key = key;  //将要查找的数据放在工作单元中    while (RL.data[i].key != key)    {        i--;    }    return i;    //查找成功返回下标,不成功返回0(即查找到工作单元还未找到待查数据)}//折半查找int MidSearch(RecordList RL, int key){    int low = 1;    int high = RL.length;    while (low <= high)    {        int mid = (low + high) / 2;        //若查找到,直接返回mid下标        if (RL.data[mid].key == key)        {            return mid;        }        //待查找的数据>中间值,使low = mid + 1,继续在右半区间查找        else if (RL.data[mid].key > key)        {            low = mid + 1;        }        //待查找的数据<中间值,使high = mid - 1,继续在左半区间查找        else        {            high = mid - 1;        }    }    return 0;}int main(void){    //RL长度为10,RL.data[0].key初始化为0,原本数据下标从1开始存储    RecordList RL = { 10, 0, 24, 10, 15, 68, 35, 72, 41, 48, 22, 67 };    int input = 0;    printf("请输入待查找的数据: ");    scanf("%d", &input);    printf("经顺序查找,待查找的元素下标为: %d\n", SeqSearch(RL, input));    printf("经折半查找,待查找的元素下标为: %d\n", MidSearch(RL, input));}

分块查找
首先将列表分成若干个块(子表)。一般情况下,块的长度均匀,最后一块可以不满。每块中元素任意排列,即块内无序,但块与块之间有序。
构造一个索引表。其中每个索引项对应一个块并记录每块的起始位置,以及每块中的最大关键字(或最小关键字)。索引表按关键字有序排列。
这里写图片描述