zoukankan      html  css  js  c++  java
  • 查找->静态查找表->折半查找(有序表)

    文字描述

      以有序表表示静态查找表时,可用折半查找算法查找指定元素。

      折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等于给定值或者查找区间的大小小于零时(表明查找不成功)为止。

    示意图

    算法分析

      折半查找过程可以用一颗二叉判定树来表示,而具有n个结点的判定树的深度为[log2n]+1,所以折半查找法在查找成功和不成功时,与给定值进行比较的关键字个数都不会超过[log2n]+1. 现讨论折半查找算法的平均查找长度。

       为讨论方便,假设有序表长度为n=2h-1,则描述折半查找的判定树是深度为h的满二叉树。假设每个记录的查找概率相等Pi = 1/n, 则折半查找查找成功的平均查找长度

      当n足够大时,平均查找长度约为log2(n+1)-1 可见,折半查找的效率比顺序查找要高,但是折半查找只适用于有序表,且限于顺序存储结构,对线性链表无法有效地进行折半查找。 

    代码实现

     1 /*
     2  ./a.out 5 13 19 21 37 56 64 75 80 88 92
     3  */
     4 #include <stdio.h>
     5 #include <stdlib.h>
     6 
     7 #define EQ(a, b)  ((a) == (b))
     8 #define LT(a, b)  ((a) <  (b))
     9 #define LQ(a, b)  ((a) <= (b))
    10 #define MAX_SIZE 50
    11 #define DEBUG
    12 
    13 typedef int KeyType;
    14 typedef char InfoType;
    15 /*数据元素类型定义*/
    16 typedef struct{
    17     //关键字域
    18     KeyType key;
    19     //其他域
    20     InfoType otherinfo;
    21 }ElemType;
    22 /*静态查找表的顺序存储结构*/
    23 typedef struct{
    24     //数据元素存储空间基址,建表时按实际长度分配,0号单元留空
    25     ElemType *elem;
    26     //表长度
    27     int length;
    28 }SSTable;
    29 
    30 /*折半查找算法
    31  *
    32  *顺序表中的元素应该按照由小到大顺序排列.
    33  *
    34  *在顺序表ST中顺序查找其关键字等于key的数据元素。
    35  *若找到,则函数值为该元素在表中的位置,否则为0
    36  */
    37 int Search_Bin(SSTable ST, KeyType key){
    38     //置区间初值
    39     int low = 1;
    40     int high = ST.length;
    41     int mid = (low+high)/2;
    42     while(low<=high){
    43         mid = (low+high)/2;
    44         if(EQ(ST.elem[mid].key, key)){
    45             //找到待查元素
    46             return mid;
    47         }else if(LT(ST.elem[mid].key, key)){
    48             //继续在后半区间查找
    49             low = mid+1;
    50         }else{
    51             //继续在前半区间查找
    52             high = mid-1;
    53         }
    54     }
    55     return 0;
    56 }
    57 
    58 //顺序打印顺序表中的数据元素
    59 void print_Seq(SSTable ST){
    60     int i = 0;
    61     for(i=1; i<= ST.length; i++){
    62         printf("[%d]=%d/%c; ", i, ST.elem[i].key, ST.elem[i].otherinfo);
    63     }
    64     printf("
    ");
    65 }
    66 
    67 int main(int argc, char *argv[])
    68 {
    69     int i = 0, loc = 0, key=0;
    70     ElemType arr[MAX_SIZE+1] = {0};
    71     for(i=1; i<argc; i++){
    72         arr[i].key = atoi(argv[i]);
    73         arr[i].otherinfo = 'a'+i-1;
    74     }
    75     SSTable ST;
    76     ST.length = i-1;
    77     ST.elem = arr;
    78 #ifdef DEBUG
    79     printf("输入了数据:");
    80     print_Seq(ST);
    81 #endif
    82     while(1){
    83         printf("输入待查找的key值(负值表示结束):");
    84         scanf("%d", &key);
    85         if(key < 0)
    86             break;
    87         loc = Search_Bin(ST, key);
    88         printf("key值为%d的位置在%d
    ", key, loc);
    89     }
    90     return 0;
    91 }
    折半查找(有序表)

    运行

  • 相关阅读:
    不使用SpringBoot如何将原生Feign集成到Spring中来简化http调用
    干货!从Tomcat执行流程了解jsp是如何被解析的,错误提示是哪里生成的。
    对TCP三次握手四次分手还不清楚的速度进,超简单解析,明白了就很好记!
    SpringCache与redis集成,优雅的缓存解决方案
    高可用的Spring FTP上传下载工具类(已解决上传过程常见问题)
    Hibernate级联之一对多和inverse解析
    Spring的面向切面
    归并排序:步骤讲解与代码实现
    关于操作系统中多个fork()会创建几个进程的理解
    win-sudo插件解决Git bash 执行脚本报错问题 bash: sudo: command not found
  • 原文地址:https://www.cnblogs.com/aimmiao/p/9483080.html
Copyright © 2011-2022 走看看