{静态查找表 + 动态查找表}
    所谓动态,就是,找的时候没有则添加,或者能删除

  关键字:primary key:用来表示查找表中的一条记录
    {主关键字 + 次关键字}
    主关键字是唯一的,用来唯一的标识查找表中的一条记录

(一)静态查找表

一、顺序表
  类似于数组,顺序存储,在表中有位置,查找即给定关键字,遍历这个表,找到其位置或给出整条记录;
  可以设置“哨兵” ,即标记0号元素就是要找的关键字:这样可以减去每次判断是否查找结束的麻烦,平均时间几乎减少一半

  优化:
    若访问频度不同,则设置频度域,根据需要调整位置,如每次将刚刚访问过得节点放在最后。

intsearch_Seq(SSTable ST,KeyType key){
//在顺序表ST中 找key
ST.elem[].key = key;
for(int i = ST.Length;!EQ(ST.elem[i].key,key),--i);
return i; //找不到返回0
}

算法复杂度分析:

  最坏条件下:O(n)
  平均:
    (1+2+...+n) / n (等概率被查找到的情况下)
    O((1+n)/2)
  若考虑查找不成功,则查找不成功的情况都是查找n+1次。
  那么:
    O((n+1)*3/4)

  def:
  平均查找长度:为确定就在查找表中的位置,需和给定值进行比较的关键字的个数的期望值称为查找成功时的平均查找长度
  即:
    ASL = 求和(pi * Ci)
    Ci为第i元素查找的步数

二、 有序表的查找
  主要讲三种,第一是经典的二分 直接贴代码

int Search_Bin(SSTable ST,KeyType key) {
int low = ;
int high = ST.Length;
int mid;
while(low<=high){
mid = (low+high)/;
if(EQ(key,ST.elem[mid].key)){
return min;
}else if(LT(key,ST.elem[mid].key)){
high = mid - ;
}else{
low = mid + ;
}
}
return ;
}

二分法的复杂度分析:(面试等常问的)
  将查找过程构建成一棵树,树的节点是每次访问的mid,这叫判定树
  由于树的深度h,定点数n = 2^h-1
  同一深度上的节点被查找需要查找走的步数就是深度h
  那么:
  平均查找,在等概率下:
    ASL = (求和i从1到最高层h(i*2^(i-1)))/n
  因为,第i层上要比较i次,第i层有2^(i-1)个结点

  当每个节点被查找到的概率不同时,二分查找可能并不是最优的,最优的是:
  PH = 求和(p*c)的查找,即判定树的带权内路径长度之和最小
  但这样做很复杂,可以以一种求折中的方法:求次优查找树

  思想:
    求一个结点,它的左右两边的点被查找到的概率最大可能性的相等, 则该点设置为mid
    递归,查找左子树、右子树

  实现:
    为了方便,设置权值之和SWi:即从开始到第i点的权值之和
    则每次查找一个点,只要计算该点右边之和减去左边的(各自区间内) ,取最小点

  细节注意:
    这并没有考察单个关键字的权值,有的时候,被选作根(mid)的关键字的权值比与他相邻的关键字的权值小
    此时应做调整

  复杂度分析:
    构造一棵次优查找树,复杂度是:
       O(nlogn)
  算法实现:

    //建立树T,根节点T,使用:R是查找表,sw是其权值,low-high是当前区间
int i = low;
float min = fabs(R[high] - R[low]);
float dw = sw[high] + sw[low-];
for(int j = low+;j<=high;j++){
if(fabs(dw - sw[j] - sw[j-]) < min){
min = dw - sw[j] - sw[j-];
i = j;
}
}
//i作为mid
T = (BiTree)malloc(sizeof(BiTNode));
T->data = R[i];
if(i == low){
T->lchild = NULL;
}else{
SecondOptimal(T->lchild,R,sw,low,i-);
} if(i == high){
T->rchild = NULL;
}else{
SecondOptimal(T->rchild,R,sw,i+,high);
}
}

综合如下:

typedef BiTree SOSTree;
Status CreateSOSTree(SOSTree &T,SSTable ST){
if(ST.Length == ){
T = NULL;
}
else{
findSW(sw,ST);//建立sw数组,权值和
SecondOptimal(T,ST.elem,sw,,ST.Length);
}
return OK;
}

静态查找还有:斐波那契、插值查找

  斐波那契:
    Fn = Fn-1 + Fn-2;
    F1 = 1;
    F0 = 0;
  斐波那契查找就是:
    假设表长我某个斐波那契值-1,即n = Fu-1;
    则在F(u-1)与key比较
    找不到就:
      if key<F(u-1).key:
        在1..F(u-1)中找
      else:
        在F(u-1)+1 ... F(u) 中找
  分析:
    平均复杂度比二分好,但最坏情况下的一次查找不如二分

  而插值查找:
    每次比较的i(相当于二分中的mid),i是有公式算的。
    平均性能比二分好。

【C/C++】查找(一):静态查找表的更多相关文章

  1. 查找->静态查找表->次优查找(静态树表)

    文字描算 之前分析顺序查找和折半查找的算法性能都是在“等概率”的前提下进行的,但是如果有序表中各记录的查找概率不等呢?换句话说,概率不等的情况下,描述查找过程的判定树为何类二叉树,其查找性能最佳? 如 ...

  2. 数据结构算法C语言实现(三十二)--- 9.1静态查找表

    一.简述 静态查找表又分为顺序表.有序表.静态树表和索引表.以下只是算法的简单实现及测试,不涉及性能分析. 二.头文件 /** author:zhaoyu date:2016-7-12 */ #inc ...

  3. C语言数据结构基础学习笔记——静态查找表

    查找:在数据集合中寻找满足某种条件的数据元素的过程称为查找. 查找表:用于查找的数据集合称为查找表,一般有以下操作:①查找是否在表中:②查找属性:③进行操作. 查找表又分为: ①静态查找表:只可以进行 ...

  4. 查找->静态查找表->折半查找(有序表)

    文字描述 以有序表表示静态查找表时,可用折半查找算法查找指定元素. 折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等 ...

  5. 查找->静态查找表->顺序查找(顺序表)

    文字描述 顺序查找的查找过程为:从表中最后一个记录开始,逐个进行记录的关键字和给定值的比较,若某个记录的关键字和给定值比较相等,则查找成功,找到所查记录:反之,若直至第一个记录,其关键字和给定值比较都 ...

  6. 查找->静态查找表->分块查找(索引顺序表)

    文字描述 分块查找又称为索引顺序查找,是顺序查找的一种改进方法.在此查找算法中,除表本身外, 还需要建立一个”索引表”.索引表中包括两项内容:关键字项(其值为该字表内的最大关键字)和指针项(指示该子表 ...

  7. c语言描述的静态查找表

    顺序表的查找: 直接循环依次和目标比较就行 有序表的查找(二分查找): int search(SS *T,Type key){ int mid; ; int high=T.length; while( ...

  8. DS静态查找- 顺序-二分-索引

    静态查找 静态表是只执行查找操作,而不执行插入.删除等操作的表. 现在常说的有五大查找方法:顺序查找.分块查找.索引查找.树查找.哈希查找. 后两种之前写过了二叉查找树和哈希表,现在回顾前面三种,它们 ...

  9. 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找

    今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...

随机推荐

  1. git branch 分支操作

    一.git分支命令 Git鼓励大量使用分支: 查看分支:git branch 创建分支:git branch <name> 切换分支:git checkout <name> 创 ...

  2. Maven的porfile与SpringBoot的profile结合使用详解

        使用maven的profile功能,我们可以实现多环境配置文件的动态切换,可参考我的上一篇博客.但随着SpringBoot项目越来越火,越来越多人喜欢用SpringBoot的profile功能 ...

  3. 配置Apache虚拟主机

    实验环境 一台最小化安装的CentOS 7.3虚拟机 配置基础环境 1. 安装apache yum install -y httpd 2. 建立虚拟主机的根目录 mkdir /var/wwwroot ...

  4. 图解SSH原理及两种登录方法

    SSH(Secure Shell)是一套协议标准,可以用来实现两台机器之间的安全登录以及安全的数据传送,其保证数据安全的原理是非对称加密. 传统的对称加密使用的是一套秘钥,数据的加密以及解密用的都是这 ...

  5. 一文看懂Transformer内部原理(含PyTorch实现)

    Transformer注解及PyTorch实现 原文:http://nlp.seas.harvard.edu/2018/04/03/attention.html 作者:Alexander Rush 转 ...

  6. 我的微信小程序第二篇

    在上一篇<我的微信小程序第一篇(入门)>中,很多人问我什么是微信小程序,在这里我要说一下这个是我的失误啦,我默认大家都知道微信小程序,其实可能行内人士都知道小程序,好多非行内朋友可能平时不 ...

  7. Python Revisited Day 04 (控制结构与函数)

    目录 4.1 控制结构 4.1.1 条件分支 4.1.2 循环 4.2 异常处理 4.2.1 捕获与产生异常 4.2.2 自定义异常 4.3 自定义函数 Tips 参数默认值为可变时 危险 4.3.1 ...

  8. 消息队列queue

    一.queue 在多线程编程中,程序的解耦往往是一个麻烦的问题,以及在socket网络编程中也会有这样的问题.recv 和send之间,如果服务端有消息,问题需要发送给客户端,而那边的recv 被主程 ...

  9. openstack-KVM-Network

    一.网络配置 1.查看网卡信息: lspci | grep Ethernet ethtool -i eth0 (qemu) info network virsh qemu-monitor-comman ...

  10. node path

    1.path.basename(path[, ext]) ● path <string> ● ext <string> An optional file extension ● ...