查找算法

查找算法

你离开我真会死。 提交于 2020-02-19 23:11:45
目录 折半查找 线性索引查找 折半查找 折半查找又称为二分查找,它的前提是记录的关键码有序,线性表必须采用顺序存储。折半查找的思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。 假设我们现在有这样-一个 有序表数组{0,1,16,24,35,47,59,62,73,88,99}16,除0下标外共10个数字。对它进行查找是否存在62这个数。我们来看折半查找的算法是如何工作的。 int Binary_Search(int *a, int n, int key) { int low, high, mid; low = 0; /*定义最低下标为记录首位*/ high = n; /*定义最高下标为记录末位*/ while (low <= high) { mid = (low + high) / 2; /*折半*/ if (key < a[mid]) /*若查找值比中值小*/ { high = mid - 1; /*最高下标调整到中位下标小一位*/ } else if (key > a[mid]) /*若查找值比中值大*/ { low - mid + 1; /

查找素数

人盡茶涼 提交于 2020-02-19 07:24:58
转载 素数的定义很简单,如果一个数如果只能被 1 和它本身整除,那么这个数就是素数。 不要觉得素数的定义简单,恐怕没多少人真的能把素数相关的算法写得高效。比如让你写这样一个函数: // 返回区间 [2, n) 中有几个素数 int countPrimes ( int n ) // 比如 countPrimes(10) 返回 4 // 因为 2,3,5,7 是素数 你会如何写这个函数?我想大家应该会这样写: int countPrimes ( int n ) { int count = 0 ; for ( int i = 2 ; i < n ; i ++ ) if ( isPrim ( i ) ) count ++ ; return count ; } // 判断整数 n 是否是素数 boolean isPrime ( int n ) { for ( int i = 2 ; i < n ; i ++ ) if ( n % i == 0 ) // 有其他整除因子 return false ; return true ; } 这样写的话时间复杂度 O(n^2),问题很大。首先你用 isPrime 函数来辅助的思路就不够高效;而且就算你要用 isPrime 函数,这样写算法也是存在计算冗余的。 先来简单说下如果你要判断一个数是不是素数,应该如何写算法。只需稍微修改一下上面的 isPrim

python常用排序算法

空扰寡人 提交于 2020-02-16 22:55:41
常见排序算法 算法:一个计算过程,解决问题的方法 程序 = 数据结构 + 算法 1.算法基本概念 1.时间复杂度 用什么方式来体现算法运行的快慢? 通过运行的次数表示时间复杂度 示例: print("hello world") print("hello python") print("hello algorithm") #以上时间复杂度O(1) for i in range(n): print("hello world") for j in range(n): print("hello world") #时间复杂度O(n**2) while n>1: print(n) n = n//2 时间复杂度记为O(log 2 n)或O(log n) 当算法过程出现循环折半的时候复杂度式子中会出现log n 时间复杂度小结 时间复杂度是用来计算算法运行的时间的一个式子(单位) 一般来说,时间复杂度高的算法比复杂度低的算法慢。 创建的时间复杂度(按效率排序) O(1) < O(logn) < O(nlogn) < O(n2) < O(n2 log n) < O(n3) 复杂问题的时间复杂度 O(n!) O(2**n) O(n**n) 如何简单快速地判断算法复杂度 快速判断算法复杂度,适用于绝大多数简单情况 确定问题规模n 循环减半过程---> log n k层关于n的循环 --->n**k

查找链表中间节点 -- C语言

喜夏-厌秋 提交于 2020-02-16 19:06:50
算法思路 1. 求链表总长度,取得一半数,遍历链表一半的数量,取得中间节点 2. 用两个指针,一个每次都移动一回,一个每两次移动一回,当第一个指针遍历完链表,后一个指针就正好指向中间 代码实现1 st_dataNode * getListMidNode(st_dataNode * head){ if(NULL == head){ printf("%s: param error\n",__func__); return NULL; } int len = 0; int m = 0; st_dataNode * mid = NULL; len = getListLen(head); m = (len / 2 - 1); // 注意应该建议,因为下标是从0开始的 if(m == 0){ return head; } mid = head; while(m > 0){ mid = mid->next; m--; } return mid; } 代码实现2 /* 通过一次遍历来完成寻找中间节点 */ st_dataNode * getListMidNode2(st_dataNode * head){ if(NULL == head){ printf("%s: param error\n",__func__); return NULL; } int step1 = 0, step2 = 0;

【数据结构】树

我的未来我决定 提交于 2020-02-16 18:28:58
树 客观世界中许多事物存在层次关系 eg:人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率 查找(Searching):给定某个关键字K,从集合R中找出关键字与K相同的记录 静态查找:集合中记录是固定的 没有插入和删除操作,只有查找 动态查找:集合中记录是动态变化的 除查找,还可能发生查找和删除 静态查找 顺序查找 typedef struct LNode *List; struct LNode{ ElementType Element[MAXSIZE]; int Length; } int SequentialSearch(List Tb1, ElementType K){ int i; Tb1->Element[0]=K;//哨兵!这样可以减少判断 for(i=Tb1->Length;Tb1->Element[i]!=K;i--); return i; } 二分查找 Binary Search O(log(n)) 假设n个数据元素的关键字满足有序 \(k_1<k_2<k_3<...<k_n\) ,并且是连续存放(数组),那么可以进行二分查找。 typedef LNode *List; struct LNode{ ElementType Element[MAXSIZE]; int Length; } int BinarySearch(List PtrL

哈希是什么?为什么哈希存取比较快?

随声附和 提交于 2020-02-16 07:56:35
  不太恰当的比喻:     XM 指的是“小明”,也指的是“小萌”     XM就是哈希值,小明和小萌就是拥有同一个哈希值的,存在同一个链表的元素。     想要获取小萌,首先使用hashcode获取到这两个人,然后再通过equals获取到小萌。   个人理解      哈希表其实就是一个一维数组,而数组中的每一个元素都是一个单向链表而已。这样的数据结构 解决了数组的增删元素的不足和链表的查询效率的不足 。    数组是存在连续的存储空间,而链表的存储空间不连续 --------------------------------   哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。   哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。   哈希通过将单向数学函数(有时称为“哈希算法”

查找算法

自闭症网瘾萝莉.ら 提交于 2020-02-15 08:39:55
查找算法 java中,我们常用的查找有四种: 1. 顺序(线性)查找 2. 二分查找 / 折半查找 3. 插值查找 4. 斐波那契查找 线性查找算法 代码 package com . search ; public class SeqSearch { 来源: CSDN 作者: DuanXS97 链接: https://blog.csdn.net/qq_43618030/article/details/104314649

数据库MySQL:B+ Tree

匆匆过客 提交于 2020-02-14 01:27:49
索引 加速查询的数据结构 索引常见数据结构 顺序查找:time: O(n),大数据量此算法效率糟糕。 二叉树查找:time:O(logn),二叉查找树可能不平衡。 hash索引:time:O(1),无法满足范围查找。 红黑树:time:O(h) = O(logn) B Tree B+ Tree 来源: https://www.cnblogs.com/xiaobaizzz/p/12306028.html

数据结构与算法(4)

纵饮孤独 提交于 2020-02-14 01:16:08
1 冒泡排序 2 插入排序 3 选择排序 4 归并排序 5 线性查找 6 二分查找 1 冒泡排序 1.1 问题 冒泡排序是一种著名的排序方法。 冒泡排序的过程是这样的,首先,将待排序的数组中的第一个元素与第二个元素相对比,如果这两个元素的大小顺序不是我们要求的顺序,则将它们交换过来。然后,将待排序的数组中的第二个元素与第三个元素相对比,如果这两个元素的大小顺序也不是我们要求的顺序,则也将它们交换过来。下一步,是对比第三个元素与第四个元素,直至倒数第二个元素与最后一个元素相对比。这样一趟对比下来,小的数据元素会一点一点的往前放,而大的数据元素会一点一点的往后放。反复多趟的这样对比,直到所有数据都排好序为止。 1.2 方案 为了理解冒泡排序算法,我们先假设有一个长度为10的数组,数组内容如图-1所示: 图-4中的数组元素为无序状态,现需要将数组内的元素排序成从小到大的升序状态。可以先进行第一趟比较。首先比较第1个和第2个数,也就是数组第一个元素3和数组第二个元素2,将小数放前,大数放后。交换后如图-2所示: 然后,将图-2中的第2个和第3个数,也就是数组第二个元素3和数组第三个元素4,进行对比,由于3小于4,所以不进行交换。接着将图-2中的第3个和第4个数对比后发现也不需要交换。这样依次进行对比,直到图-2中的第7个和第8个数,也就是数组第七个元素9和数组第八个元素1,对比时

从原理到优化,深入浅出数据库索引

半世苍凉 提交于 2020-02-13 23:44:06
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。 数据库查询是数据库的最主要功能之一,我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化,这篇文章对索引做一个系统的梳理,希望对大家有帮助。 一、MySQL有哪些索引类型 索引的分类可以从多个角度进行,下面分别从数据结构,物理存储和业务逻辑三个维度进行划分。 1、从数据结构角度 (1)B+树索引(O(log(n))) 关于B+树索引,后面会深入解析 (2)hash索引 仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询 其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引 只有Memory存储引擎显示支持hash索引 (3)FULLTEXT索引 现在MyISAM和InnoDB引擎都支持了 (4)R-Tree索引 用于对GIS数据类型创建SPATIAL索引 2、从物理存储角度 (1)聚集索引(clustered index) 正文内容按照一个特定维度排序存储,这个特定的维度就是聚集索引; Innodb存储引擎中行记录就是按照聚集索引维度顺序存储的,Innodb的表也称为索引表;因为行记录只能按照一个维度进行排序