一、什么是查找

  • 查找(Searching)就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。
  • 查找表(Search Table):由同一类型的数据元素(或记录)构成的集合
  • 关键字(Key):数据元素中某个数据项的值,又称为键值。
  • 主键(Primary Key):可唯一地标识某个数据元素或记录的关键字。

  搜索是在一个项目集合中找到一个特定项目的算法过程。搜索通常的答案是真的或假的,因为该项目是否存在。 搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找。

二、无序表查找

也就是数据不排序的线性查找,遍历数据元素。
算法分析:最好情况是在第一个位置就找到了,此为O(1);最坏情况在最后一个位置才找到,此为O(n);所以平均查找次数为(n+1)/2。最终时间复杂度为O(n)

# 最基础的遍历无序列表的查找算法
# 时间复杂度O(n) def sequential_search(lis, key):
length = len(lis)
for i in range(length):
if lis[i] == key:
return i
else:
return False if __name__ == '__main__':
LIST = [1, 5, 8, 123, 22, 54, 7, 99, 300, 222]
result = sequential_search(LIST, 123)
print(result)

三、二分查找(Binary Search)

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

算法核心:在查找表中不断取中间元素与查找值进行比较,以二分之一的倍率进行表范围的缩小。

1、二分查找的python代码实现

def binary_search(lis, key):
low = 0
high = len(lis) - 1
time = 0
while low < high:
time += 1
mid = int((low + high) / 2)
if key < lis[mid]:
high = mid - 1
elif key > lis[mid]:
low = mid + 1
else:
# 打印折半的次数
print("times: %s" % time)
return mid
print("times: %s" % time)
return False if __name__ == '__main__':
LIST = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
result = binary_search(LIST, 1)
print(result)

运行结果为:

查找次数为: 3
下表为:0

2、二分查找的C语言代码实现

//  main.m
// 二分查找
// Created by 侯垒 on 2019/7/1.
// Copyright © 2019 可爱的侯老师. All rights reserved. # include <stdio.h>
int binary_search(int array[],int key,int len)
{
int low = ;
int high = len-;
int time = ;
while (low<high)
{
time++;
int mid = (int)(low+high)/;
if (key<array[mid])
{
high = mid-;
}
else if(key>array[mid])
{
low = mid+;
}
else
{
// 打印这本的次数
printf("查询次数 = %d\n",time);
return mid;
}
}
printf("查询次数 = %d\n",time);
return -;
} int main(int argc, const char * argv[])
{
int array[] = {, , , , , , , , , , };
int index = binary_search(array, , );
printf("下标是 = %d\n",index);
return ;
}

运行结果为:

查询次数 = 

下标是 = 

四、插值查找

  在介绍插值查找之前,首先考虑一个新问题,为什么上述算法一定要是折半,而不是折四分之一或者折更多呢?

  打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查?很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前或往后翻。

  同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀分布的数组中查找5, 我们自然会考虑从数组下标较小的开始查找。

  经过以上分析,折半查找这种查找方式,不是自适应的(也就是说是傻瓜式的)。二分查找中查找点计算如下:

  mid=(low+high)/2, 即mid=low+1/2*(high-low);

  通过类比,我们可以将查找的点改进为如下:

  mid=low+(key-list[low])/(list[high]-list[low])*(high-low),

  也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。

  基本思想:基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。

  注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。

  复杂度分析:查找成功或者失败的时间复杂度均为O(log(n))。

1、插值查找的python代码实现

def chazhi_search(lis, key):
low = 0
high = len(lis) - 1
time = 0
while low < high:
time += 1
# 计算mid值是插值算法的核心代码
mid = low + int((key - lis[low])/(lis[high] - lis[low]) * (high - low))
print("mid=%s, low=%s, high=%s" % (mid, low, high))
if key < lis[mid]:
high = mid - 1
elif key > lis[mid]:
low = mid + 1
else:
# 打印查找的次数
print("查询次数: %s" % time)
return mid
print("times: %s" % time)
return False if __name__ == '__main__':
LIST = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
index = chazhi_search(LIST, 1)
print("下标为:%s"%index)

运行结果为:

mid=, low=, high=
查询次数:
下标为:

2、插值查找的C语言代码实现

//  main.m
// 插值查找
// Created by 侯垒 on 2019/7/1.
// Copyright © 2019 可爱的侯老师. All rights reserved. #include<stdio.h>
int chazhi_search(int array[],int key,int len)
{
int low = ;
int high = len-;
int time = ; while (low<high)
{
time++;
// 计算mid值是插值算法的核心代码
int mid = low + (int)((key - array[low])/(array[high]-array[low])*(high-low));
printf("mid=%d, low=%d, high=%d\n",mid, low, high);
if (key<array[mid])
{
high = mid-;
}
else if (key>array[mid])
{
low = mid+;
}
else
{
// 打印查找的次数
printf("查询次数:%d\n",time);
return mid;
}
}
printf("查询次数:%d\n",time);
return -;
} int main(int argc, const char * argv[]) {
int arr[] = {, , , , , , , , , , };
int index = chazhi_search(arr, , );
printf("下标为:%d\n",index); return ;
}

运行结果为:

mid=, low=, high=
查询次数:
下标为:

python算法与数据结构-常用查找算法一(37)的更多相关文章

  1. 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)

    本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...

  2. 常用查找算法(Java)

    常用查找算法(Java) 2018-01-22 1 顺序查找 就是一个一个依次查找 2 二分查找 二分查找(Binary Search)也叫作折半查找. 二分查找有两个要求, 一个是数列有序, 另一个 ...

  3. C++ STL 常用查找算法

    C++ STL 常用查找算法 adjacent_find() 在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器.否则返回past-the-end. ...

  4. 数据结构和算法(Golang实现)(26)查找算法-哈希表

    哈希表:散列查找 一.线性查找 我们要通过一个键key来查找相应的值value.有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链 ...

  5. 数据结构和算法(Golang实现)(27)查找算法-二叉查找树

    二叉查找树 二叉查找树,又叫二叉排序树,二叉搜索树,是一种有特定规则的二叉树,定义如下: 它是一颗二叉树,或者是空树. 左子树所有节点的值都小于它的根节点,右子树所有节点的值都大于它的根节点. 左右子 ...

  6. 数据结构和算法(Golang实现)(28)查找算法-AVL树

    AVL树 二叉查找树的树高度影响了查找的效率,需要尽量减小树的高度,AVL树正是这样的树. 一.AVL树介绍 AVL树是一棵严格自平衡的二叉查找树,1962年,发明者Adelson-Velsky和La ...

  7. 数据结构和算法(Golang实现)(29)查找算法-2-3树和左倾红黑树

    某些教程不区分普通红黑树和左倾红黑树的区别,直接将左倾红黑树拿来教学,并且称其为红黑树,因为左倾红黑树与普通的红黑树相比,实现起来较为简单,容易教学.在这里,我们区分开左倾红黑树和普通红黑树. 红黑树 ...

  8. ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)

    ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)

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

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

随机推荐

  1. SPSS 习题-2

    1.有关SPSS数据字典的说法,正确的是:  AA. SPSS 数据集的数据字典可以复制到其他数据集中B. SPSS数据集的数据字典是不能复制的C. SPSS的数据字典可以通过“复制”和“粘贴”在不同 ...

  2. CF1281B Azamon Web Services

    思路: 贪心,找到将s至多交换一次所能得到的字典序最小的字符串,再与c比较. 实现: #include <bits/stdc++.h> using namespace std; int m ...

  3. 【GStreamer开发】GStreamer基础教程09——收集媒体信息

    目标 有时你需要快速的了解一个文件(或URI)包含的媒体格式或者看看是否支持这种格式.当然你可以创建一个pipeline,设置运行,观察总线上的消息,但GStreamer提供了一个工具可以帮你做这些. ...

  4. 高级UI-属性动画

    在3.0以前,动画效果主要为补间动画(TweenAnimation)和帧动画(FrameAnimation),从3.0开始加入了属性动画,其本质就是不断地改变控件的属性,从而达到复杂的动画效果,其效果 ...

  5. 什么?Iconfont终于可以支持彩色图标了

    如果你对iconfont有所了解,那你一定对这次iconfont做出的更新产生兴趣.没错,iconfont目前已经升级为iconfont+,并且能够支持大家都很期待的彩色图标. 之前,大家也以文字的形 ...

  6. noVNC使用——访问多台vnc

    一.模拟实验环境 1.CentOS6.8系统2.KVM环境3.使用KVM环境的两个系统(Windows,Linux)4.noVNC5.vncserver 二.实验过程1.在kvm的环境下,通过xml创 ...

  7. pytorch1.0批训练神经网络

    pytorch1.0批训练神经网络 import torch import torch.utils.data as Data # Torch 中提供了一种帮助整理数据结构的工具, 叫做 DataLoa ...

  8. [转帖]谷歌宣称首次实现量子优越性,IBM“不服”,中国同行咋看?

    谷歌宣称首次实现量子优越性,IBM“不服”,中国同行咋看? 投递人 itwriter 发布于 2019-10-24 15:46 评论(7) 有306人阅读 原文链接 [收藏] « » https:// ...

  9. [转帖]亚马逊彻底去掉 Oracle 数据库:迁移完成

    亚马逊彻底去掉 Oracle 数据库:迁移完成 https://mp.weixin.qq.com/s/KFonq8efDZ5K6x4YzIVbbg 云头条的信息挺不错的.. 2019 年 10 月 1 ...

  10. 多线程(7)— JDK对锁优化的努力

    JDK内部的“锁”优化策略 1. 锁偏向 锁偏向是针对加锁操作的优化手段,核心思想是:如果一个线程获得了锁,那么锁就进入偏向模式,当这个线程再次请求锁时,无须再做任何同步操作,这样就节省了大量有关锁申 ...