查找——基于线性表的查找法

目录

一、顺序查找法

1.1 算法实现

1.1.1 算法一:设置监视哨的顺序查找法

1.1.2 算法二:不设置监视哨的顺序查找法

1.2 算法性能分析

二、折半查找法

2.1 算法实现

2.3 算法性能分析


基于线性表的查找法具体可分为顺序查找法、折半查找法、分块查找法。


一、顺序查找法

基本思想:用所给关键字与线性表中各元素的关键字逐个比较,直到成功或失败。

存储结构通常为顺序结构,也可为链式结构。这里采用的是顺序结构。

#define LIST_SIZE 20
typedef struct {
    KeyType key;
    OtherType other_data;
} RecordType;

typedef struct {
    RecordType r[LIST_SIZE+1]; /* 保留r[0]为工作单元 */
    int length;
} RecordList;

 

1.1 算法实现

1.1.1 算法一:设置监视哨的顺序查找法

算法思想:在表的一端设置一个称为“监视哨”的附加单元,存放要查找元素的关键字。从表的另一端开始查找。如果在表中找到要查找的元素,则返回对应的下标;否则意味着在监视哨位置找到该元素,返回下标0,代表查找失败。

int SeqSearch(RecordList L, KeyType k) {
    L.r[0] = k;
    int i = L.length;
    while (L.r[i].key != k) --i;
    return i;
}

1.1.2 算法二:不设置监视哨的顺序查找法

int SeqSearch(RecordList L, KeyType k) {
    int i = L.length;
    while (i >= 1 && L.r[i].key != k) --i;
    return i;
}

算法二与算法一相比,循环控制条件中增加了i>=1,用以判断查找过程是否越界。加设监视哨可省去这个条件,从而提高查找效率。

 

1.2 算法性能分析

 


二、折半查找法

折半查找法对要查找的列表有两个要求:

  • 必须采用顺序存储结构
  • 必须按关键字大小有序排列

 

2.1 算法实现

算法思想:

  1. 首先取表中间记录的关键字与待查找关键字作比较。如果两者相等,则查找成功;否则,以中间位置为准将表分为左、右两个半区。
  2. 如果该记录的关键字大于待查找关键字,则进一步查找左半区;否则,进一步查找右半区。
  3. 重复1、2,直到查找成功,或所查找的区域无记录,查找失败。
int BinSearch(RecordList L, KeyType k) {
    low = 0;
    high = L.length - 1;
    while (low <= high) {
        mid = (low + high) / 2;
        if (L.r[mid].key == k) return mid;
        else if (L.r[mid].key > k) high = mid - 1;
        else low = mid + 1;
    }
    return 0;
}

注意:根据具体的数组存储情况设置low和high的值。 


为方便理解,给出一个使用折半查找法的例子(查找关键字50,最终查找失败)。

为方便观察,蓝色标明当前循环中mid的值,黄色标明上一轮循环中mid的值。

 

2.3 算法性能分析

根据折半查找法,画出上述例子的查找过程。

根据分析,可以得出以下结论。

查找成功: 比较次数 = 路径上的结点数 = 结点的层数 

查找失败: 比较次数 = 路径上的结点数(即绿色结点的数目)

再结合二叉树的性质,计算出平均查找长度(假设判定树是一个满二叉树)。

 


 回顾:二叉树的性质。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 线性是一种常用的数据结构,用于存储一系列按顺序排列的元素。线性的实现方式有多种,比如顺序和链等。 在进行线性的单词频率统计时,可以使用哈希或者红黑树等数据结构来实现。其中,哈希的查询和插入操作时间复杂度均为O(1),因此在处理大规模数据时,哈希的效率更高。 如果需要进行数据的排序和查找操作,可以使用排序算来实现。常见的排序算有冒泡排序、插入排序、选择排序、快速排序和归并排序等。其中,快速排序和归并排序的时间复杂度均为O(nlogn),因此在处理大规模数据时,这两种算的效率更高。 当需要在线性中进行查找操作时,可以使用顺序查找或者二分查找。顺序查找的时间复杂度为O(n),而二分查找的时间复杂度为O(logn),因此在处理大规模数据时,二分查找的效率更高。但是,二分查找要求线性中的元素必须是有序的。 希望这些信息能够对您有所帮助。 ### 回答2: 基于线性实现单词的词频统计与查找可以通过使用数组或链来实现。在此以使用数组为例进行说明。 首先,我们可以创建一个包含单词和对应词频的结构体,如: ```c struct WordFrequency { char word[50]; int frequency; }; ``` 接下来,我们可以定义一个包含上述结构体的数组,用于存储单词和对应的词频信息,如: ```c struct WordFrequency wordList[1000]; int wordCount = 0; ``` 其中,wordCount用于记录数组中已存储的单词数量。 当需要进行词频统计时,可以遍历文本文件,读取每个单词,并在线性中进行查找。若找到相同的单词,则将其对应的词频加一;若未找到,则在数组中新增一个结构体来存储该单词及其初始词频。具体代码如下: ```c void wordFrequencyCount(char* filename) { FILE* file = fopen(filename, "r"); char word[50]; while (fscanf(file, "%s", word) != EOF) { int found = 0; for (int i = 0; i < wordCount; i++) { if (strcmp(word, wordList[i].word) == 0) { wordList[i].frequency++; found = 1; break; } } if (!found) { strcpy(wordList[wordCount].word, word); wordList[wordCount].frequency = 1; wordCount++; } } fclose(file); } ``` 此时,wordList中保存了每个不重复单词及对应的词频信息。 当需要查找某个词频时,只需遍历数组进行查找并返回对应的频率信息。具体代码如下: ```c int getFrequency(char* word) { for (int i = 0; i < wordCount; i++) { if (strcmp(word, wordList[i].word) == 0) { return wordList[i].frequency; } } return 0; } ``` 上述方基于线性实现了单词的词频统计与查找。通过使用数组来存储单词及对应的词频信息,我们可以快速查找并更新词频。当然,也可以使用链等其他线性结构来实现相同的功能。 ### 回答3: 基于线性实现单词的词频统计与查找可以使用数组来实现。首先,我们可以将文本中的单词逐一读取出来,然后将其存储在一个数组中。在数组中,每个单词可以与一个整数词频值对应。 对于词频统计,我们可以使用一个哈希来辅助计数。首先,遍历数组中的每个单词,通过哈希函数将其转换成一个数组下标。然后,在哈希对应的下标位置的值上加一,示该单词出现的次数。这样就可以实现每个单词的词频统计。 对于查找,我们可以遍历数组中的每个单词,与目标单词进行比较。如果找到了目标单词,则返回该单词在数组中的位置;如果没有找到,则返回一个不存在的位置值(如-1)。 基于线性实现单词的词频统计与查找的优势是简单、效率高。由于使用数组作为存储结构,可以直接通过下标来访问或修改数组中的元素,具有快速的读取和更新速度。同时,利用哈希进行统计可以减少遍历的次数,提高了词频统计的效率。 然而,基于线性实现单词的词频统计与查找也有一些不足之处。首先,使用数组存储所有的单词需要占用较大的内存空间,特别是当文本量较大时。其次,基于哈希的统计方可能存在冲突问题,即多个单词映射到同一个哈希下标的情况,需要额外的处理。因此,在实际应用中还需要根据具体的需求选择合适的算和数据结构来实现单词的词频统计与查找

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值