查找算法

常用算法——二分查找(非递归)

不羁的心 提交于 2020-01-30 07:32:40
二分查找(非递归) 基本介绍 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表 必须采用顺序存储结构 ,而且表中元素按关键字 有序排列 。 首先,假设表中元素是按 升序排列 ,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。 比较次数 a<log 2 n<b 算发时间复杂度 O(n)=O(log 2 n) 代码实现 以arr = { 1, 3, 8, 10, 11, 67, 100 }为例 public class BinarySerch { public static void main ( String [ ] args ) { int [ ] arr = { 1 , 3 , 8 , 10 , 11 , 67 , 100 } ; // 测试二分查找 int index = binarySearch ( arr , 1 ) ; System . out . println ( "index=" + index + " 值【" + arr [ index ] + "】" ) ; } /** *

C++ 常用查找算法

牧云@^-^@ 提交于 2020-01-30 04:52:34
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include <algorithm> using namespace std; #include <vector> #include <string> #include <functional> /* find算法 查找元素 @param beg 容器开始迭代器 @param end 容器结束迭代器 @param value 查找的元素 @return 返回查找元素的位置 */ void test01() { vector<int>v; for (int i = 0; i < 10;i++) { v.push_back(i); } vector<int>::iterator pos = find(v.begin(), v.end(), 5); if (pos!=v.end()) { cout << "找到了数据:" << *pos << endl; } else { cout << "未找到" << endl; } } class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } bool operator==( const Person&p) {

哈希的原理和代价

纵饮孤独 提交于 2020-01-30 00:58:45
总结一句话,Hash是一种典型的空间换时间,代价就是需要使用更大的空间,除了要储存源数据外还要额外的储存,hash关系的数据! 【转】 哈希表和哈希函数是大学数据结构中的课程,实际开发中我们经常用到Hashtable这种结构,当遇到键-值对存储,采用Hashtable比ArrayList查找的性能高。为什么呢?我们在享受高性能的同时,需要付出什么代价(这几天看红顶商人胡雪岩,经典台词:在你享受这之前,必须受别人吃不了的苦,忍受别人受不了的屈辱),那么使用Hashtable是否就是一桩无本万利的买卖呢?就此疑问,做以下分析,希望能抛砖引玉。 1)hash它为什么对于键-值查找性能高 学 过数据结构的,都应该晓得,线性表和树中,记录在结构中的相对位置是随机的,记录和关键字之间不存在明确的关系,因此在查找记录的时候,需要进行一系列的 关键字比较,这种查找方式建立在比较的基础之上,在java中(Array,ArrayList,List)这些集合结构采用了上面的存储方式。 比如,现在我们有一个班同学的数据,包括姓名,性别,年龄,学号等。假如数据有 姓名 性别 年龄 学号 张三 男 15 1 李四 女 14 2 王五 男 14 3 假如,我们按照姓名来查找,假设查找函数FindByName(string name); 1)查找“张三” 只需在第一行匹配一次。 2)查找"王五" 在第一行匹配

哈希的原理和代价<转>

本秂侑毒 提交于 2020-01-30 00:55:59
哈希表和哈希函数是大学数据结构中的课程,实际开发中我们经常用到Hashtable这种结构,当遇到键-值对存储,采用Hashtable比ArrayList查找的性能高。为什么呢?我们在享受高性能的同时,需要付出什么代价(这几天看红顶商人胡雪岩,经典台词: 在你享受这之前,必须受别人吃不了的苦,忍受别人受不了的屈辱 ),那么使用Hashtable是否就是一桩无本万利的买卖呢?就此疑问,做以下分析,希望能抛砖引玉。 1)hash它为什么对于键-值查找性能高 学过数据结构的,都应该晓得,线性表和树中,记录在结构中的相对位置是随机的,记录和关键字之间不存在明确的关系,因此在查找记录的时候,需要进行一系列的关键字比较,这种查找方式建立在比较的基础之上,在.net中(Array,ArrayList,List)这些集合结构采用了上面的存储方式。 比如,现在我们有一个班同学的数据,包括姓名,性别,年龄,学号等。假如数据有 姓名 性别 年龄 学号 张三 男 15 1 李四 女 14 2 王五 男 14 3 假如,我们按照姓名来查找,假设查找函数FindByName(string name); 1)查找“张三” 只需在第一行匹配一次。 2)查找"王五" 在第一行匹配,失败, 在第二行匹配,失败, 在第三行匹配,成功 上面两种情况,分别分析了最好的情况,和最坏的情况,那么平均查找次数应该为 (1+3)/2

算法09 五大查找之:哈希查找

牧云@^-^@ 提交于 2020-01-30 00:34:04
前面的几篇文章分别总结了: 顺序查找 、 二分查找 、 索引查找 、 二叉排序树 。这一篇文章要总结的是五大查找的最后一个:哈希查找(也称为散列查找)。提起哈希,我的第一印象就是java中的Hashtable类,它是由 key/value 的键值对组成的集合,它就是应用了哈希技术。 那什么是哈希查找呢?在弄清楚什么是哈希查找之前,我们要弄清楚哈希技术,哈希技术是在记录的存储位置和记录的 key 之间建立一个确定的映射 f(),使得每个 key 对应一个存储位置 f(key)。若查找集合中存在这个记录,则必定在 f(key) 的位置上。哈希技术既是一种存储方法,也是一种查找方法。 六种哈希函数 f(key) 的构造方法: 1、直接定址法 哈希地址:f(key) = a*key+b (a,b为常数) 这种方法的优点是:简单,均匀,不会产生冲突。但是需要事先知道 key 的分布情况,适合查找表较小并且连续的情况。 2、数字分析法 比如我们的11位手机号码“136xxxx5889”,其中前三位是接入号,一般对应不同运营公司的子品牌,如130是联通如意通,136是移动神州行等等。中间四位表示归属地。最后四位才是用户号。 若我们现在要存储某家公司员工登记表,如果用手机号码作为 key,那么极有可能前7位都是相同的,所以我们选择最后四位作为 f(key) 就是不错的选择。 3、平方取中法

常见快速搜索算法图解

喜夏-厌秋 提交于 2020-01-29 11:03:51
搜索 搜索是在一个项目集合中找到一个特定项目的算法过程。搜索通常的答案是真的或假的,因为该项目是否存在。搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找 二分查找 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。 二分查找的实现 (非递归实现) def binary_search_2 ( alist , item ) : """二分查找:while版""" n = len ( alist ) first = 0 last = n - 1 while first <= last : mid = ( first + last ) // 2 if alist [ mid ] == item : return True elif item < alist [ mid ] : last = mid - 1 else : first = mid + 1

散列

百般思念 提交于 2020-01-28 21:43:03
什么是哈希表? 原文链接:https://blog.csdn.net/yyyljw/article/details/80903391 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 哈希表hashtable(key,value) 就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。(或者:把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。) 数组的特点是:寻址容易,插入和删除困难; 而链表的特点是:寻址困难,插入和删除容易。 那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法——拉链法

哈希表

与世无争的帅哥 提交于 2020-01-28 13:41:46
1.哈希表的定义 哈希表:根据关键码值(key value)直接进行访问的数据结构,也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找速度,这个映射函数叫做哈希函数,存放记录的数组叫做哈希表。 给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。 举例:新华字典,我想要获取“按”字详细信息,去根据拼音an去查找拼音索引,首先去查an在字典的位置,得到“安”,这个过程就是键码映射。在公式里,就是通过key去查找f(key)。其中,按就是关键字(key),f(key)就是字典索引,也就是哈希函数,查到的页码4就是哈希值。 2.如何构造哈希表 根据设定的哈希函数f=H(key)和处理冲突的方法,将一组关键字映像到一个有限的连续的地址集上,并以关键字在地址集中的”象”作为记录在表中的存储位置,这一映像过程,称为构造哈希表(散列表)。 几种常见的哈希函数(散列函数)构造方法 直接定址法 取关键字或关键字的某个线性函数值为散列地址。 即 H(key) = key 或 H(key) = a*key + b,其中a和b为常数。 比如 除留余数法 取关键字被某个不大于散列表长度 m 的数 p 求余,得到的作为散列地址。对除数p的选择很重要,若p选的不好

线性表(二)

∥☆過路亽.° 提交于 2020-01-27 21:58:49
单链表 线性表链式存储结构的特点是:用一种任意的存储单元存储线性表的存储元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个数据元素ai与其直接后继数据元素a i+1之间的逻辑关系,对数据元素来说,除了存储其本身的信息之外,还需存储一个指示其直接后续的信息(即直接后续的存储位置)。这两部分信息组成数据元素ai的存储映像,称为结点。它包括两个域:其中存储数据元素信息的域称为数据域;存储直接后继存储位置的域称为指针域。指针域中存储的信息称为指针或链。n个结点(ai(1<=i<=n)的存储印象)链结成一个链表,即为 线性表 (a1,a2,a3..................an) 的链式存储结构。又由于此链表的每一个结点中只包含一个指针域,故又称 线性链表 或 单链表。 根据链表结点所含的指针个数、指针指向和指针连接方式,可将链表分为 单链表、****循环链表 和 双向链表 用于实现线性表的链式存储结构,其他形式多用于实现树和图等非线性结构。 下面对首原结点、头结点、头指针三个容易混淆的概念加以说明 首原结点 是指链表中存储第一个数据元素a1的结点。 头结点 是在首元结点之前附设的一个结点,其指针域指向首元结点。头结点的数据域可以不存储任何信息,也可存储与数据元素类型相同的其他附加信息。 头指针 是指向链表中第一个结点的指针。若链表设有头结点

二分法查找的java实现

自闭症网瘾萝莉.ら 提交于 2020-01-27 02:29:52
算法 .二分法 二分法也就是折半查找,在 有序 的数列中查找指定的元素,设定最小索引( low )和最大索引( height-1 )还有中间值mid( (low+height-1)/2 ),这种查找,如果中间值比指定元素小让low=mid+1,如果中间值比指定元素大,让height=mid-1; 以上是大体思路,下面展示两个动图,帮助理解 第一个图表示了二分法的整体过程; 第二个图表示了原方法的整体过程; 观察可得二分法的优越性! 代码实现 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Scanner; public class Main2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int arr[] = { 2, 5, 6, 8, 9, 4, 7 }; Arrays.sort(arr); int deix(索引) = getxiabiao(arr, 7); } public static int getxiabiao(int[] arr, int key) { int