查找算法

查找最小的k个元素

丶灬走出姿态 提交于 2020-03-05 12:38:52
题目: 输入n 个整数,输出其中最小的 k 个。 例如输入 1 , 2 , 3 , 4 , 5 , 6 , 7 ,8 这 8 个数字,则最小的 4 个数字为 1 , 2 , 3 和 4 。 分析: 本题最简单也最容易想到的解决方法就是把输入的n个整数排序了。当然,排序也有好多种方法,是选择排序、插入排序、快速排序还是堆排序?如果是堆排序还要分为是用大根堆还是小根堆?首先,我们当然会选择时间复杂度较低(nlogn)的排序算法了。 再仔细看下题目,题中好像没有要求我们按大小顺序输出其中的最小的k个数!仅仅要求输入这个k个数而已。这就提示我们不必对所有数据进行排序,只需找出这k个最小数而已。是不是选择排序比较合适?只需要O(n*k)就可以找到最小的k个数据。在具体化些,我们只需申请k个大小的数组存储最后的结果,如果数组未填满,我们就直接将输入的元素放入到数组中;如果数组中放满了k个元素,那么我们就需要找到当前数组中最大的元素值与刚输入的整数值比较,如果刚输入的整数值较小,则进行替换,否则继续输入…… 查找k个元素数组的最大值时间复杂度为O(k),需要进行n-k次,所以时间复杂度是O(k(n-k)),最后的平均复杂度应该是O(kn)。至于更多的思路当然还有采用具有k个元素的大根堆来实现,具体可以查看July的详细讲解 http://blog.csdn.net/v_JULY_v

Redis(2)——跳跃表

亡梦爱人 提交于 2020-03-04 22:14:26
一、跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由 William Pugh 在论文《Skip lists: a probabilistic alternative to balanced trees》中提出,是一种可以与平衡树媲美的层次化链表结构——查找、删除、添加等操作都可以在对数期望时间下完成,以下是一个典型的跳跃表例子: 我们在上一篇中提到了 Redis 的五种基本结构中,有一个叫做 有序列表 zset 的数据结构,它类似于 Java 中的 SortedSet 和 HashMap 的结合体,一方面它是一个 set 保证了内部 value 的唯一性,另一方面又可以给每个 value 赋予一个排序的权重值 score,来达到 排序 的目的。 它的内部实现就依赖了一种叫做 「跳跃列表」 的数据结构。 为什么使用跳跃表 首先,因为 zset 要支持随机的插入和删除,所以它 不宜使用数组来实现,关于排序问题,我们也很容易就想到 红黑树/ 平衡树 这样的树形结构,为什么 Redis 不使用这样一些结构呢? 性能考虑: 在高并发的情况下,树形结构需要执行一些类似于 rebalance 这样的可能涉及整棵树的操作,相对来说跳跃表的变化只涉及局部 (下面详细说); 实现考虑: 在复杂度与红黑树相同的情况下,跳跃表实现起来更简单,看起来也更加直观; 基于以上的一些考虑

29、B-树的插入、查找、删除

吃可爱长大的小学妹 提交于 2020-03-03 10:16:30
前面讨论的查找都是内查询算法,被查询的数据都在内存。当查询的数据放在外存,用平衡二叉树作磁盘文件的索引组织时,若以结点为内外存交换的单位,则找到需要的关键字之前,平均要进行lgn次磁盘读操作,而磁盘、光盘的读写时间要比随机存取的内存代价大得多。其二,外存的存取是以“页”为单位的,一页的大小通常是1024字节或2048字节。 针对上述特点,1972年R.Bayer和E.M.Cright提出了一种B-树的多路平衡查找树,以适合磁盘等直接存取设备上组织动态查找表。B-树上算法的执行时间主要由读、写磁盘的次数来决定,故一次I/O操作应读写尽可能多的信息。因此B-树的结点规模一般以一个磁盘页为单位。一个结点包含的关键字及其孩子个数取决于磁盘页的大小。 一、基本概念 B-树又称为多路平衡查找树。 一棵度为m的B-树称为m阶B_树。一个结点有k个孩子时,必有k-1个关键字才能将子树中所有关键字划分为k个子集。B-树中所有结点的孩子结点最大值称为B-树的阶,通常用m表示。从查找效率考虑,一般要求m≥3。一棵m阶的B-树或者是一棵空树,或者是满足下列要求的m叉树: (1)根结点或者为叶子,或者至少有两棵子树,至多有m棵子树。 (2)除根结点外,所有非终端结点至少有ceil(m/2)棵子树,至多有m棵子树。 (3)所有叶子结点都在树的同一层上。 (4)每个结点的结构为: (n,A0,K1,A1,K2

查找算法入门

て烟熏妆下的殇ゞ 提交于 2020-03-03 07:16:13
1.查找算法简介 通常所说的有七种比较常用的查找算法:顺序查找,二分查找,插值查找,斐波那契查找,树表查找,分块查找,哈希查找。顺序查找即是按照数据的存储结构,从前往后一次进行查找,这种方式较为低效。如果数据是按照某种顺序存储在内存中,可以按照二分查找的方式,提高查询的效率。插值查找和斐波那契查找属于对二分查找的优化。树表查找是基于树形存储结构的查找方式,常见的树形存储结构主要有二叉树,平衡二叉树和红黑树。分块查找是二分查找和顺序查找的一种改进的方法,由于只要求索引表是有序的,对块内节点并没有排序的要求,因此特别适合于节点动态变化的情况,说的通俗一点,就是将待查找的数组进行分组,确定每个分组内元素的取值范围,然后将待查找的元素在其对应的范围内进行顺序查找。哈希查找也叫散列查找,整个散列查找过程分为两步:1.在存储时,通过散列函数计算记录的散列地址,并按照此散列地址存储该记录。2.当查找的时候,一样通过散列函数计算记录的散列地址,然后访问散列地址的记录。 2.顺序查找与二分查找 本文主要是简单对顺序查找和二分查找这两个基本的查找方式进行简单的介绍,后面会重点对哈希查找和树表查找进行介绍,欢迎大家一起交流讨论,共同进步。 2.1 顺序查找 顺序查找就是按照存储顺序从前往后进行查找,没什么好说的,直接上代码。 public class shunxu { public static

算法面试

只愿长相守 提交于 2020-03-02 13:26:32
快速排序: 是一种分区交换排序算法。采用分治策略对两个子序列再分别进行快速排序,是一种递归算法。 法描述:在数据序列中选择一个元素作为基准值,每趟从数据序列的两端开始交替进行,将小于基准值的元素交换到序列前端,将大于基准值的元素交换到序列后端,介于两者之间的位置则成为了基准值的最终位置。同时,序列被划分成两个子序列,再分别对两个子序列进行快速排序,直到子序列的长度为1,则完成排序。 快速排序实现①(函数实现) def quick_sort(arr): if len(arr)<=1: return arr pivot = arr[len(arr)//2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) if __name__ == "__main__": li = [10, 22, 33, 41, 54, 55, 14, 57] print(quick_sort(li)) 快速排序实现②(列表实现) def quicksort(nums): if len(nums) <= 1: return nums

NOIP需要掌握的内容(大致

旧街凉风 提交于 2020-03-02 11:41:13
1、 排序算法(快排、选择、冒泡、堆排序、 二叉排序树 、桶排序) 2、 DFS/BFS 剪枝 哈希表 3、树 ① 遍历 ② 二叉树 ③二叉排序树(查找、生成、删除) ④堆(二叉堆、左偏树、堆排序) ⑤Trie树 4、图(图论建模) ① 最小生成树 ② 最短路径 ③计算图的传递闭包 ④ 连通分量(其中要掌握并查集技术) 强连通分量tarjin ⑤ 拓扑排序 、关键路径 ⑥哈密尔顿环 ⑦ 欧拉回路 (USACO 3.3 题1 Fence) ⑧ Bell-man Ford、SPFA(能解决负权回路) (USACO 3.2 题6 Butter) ⑨二分图(匈牙利算法)(USACO 4.2 题2 stall) 5、动态规划(背包问题只是其中一种) ① 线性动规 ② 区间动规 ③ 树形动规 ④图形动规 6、 分治 (掌握了动规分治就好学了) 7、 贪心 8、 位运算 (可以用来进行优化) 来源: https://www.cnblogs.com/GldHkkowo/p/8710834.html

查找算法之斐波那契查找

自闭症网瘾萝莉.ら 提交于 2020-03-02 10:08:36
1、什么是斐波那契数列? 1、1、2、3、5、8、13、21、34…… 斐波那契数列又被成为黄金分割数列,因为 前一项/后一项越来越趋近于0.618 由上面的数列,可以发现 除了前两项,后面每一项都是前两项的和,如3+5=8、8+13=21… 由此可以得到一下等式 F(n)=F(n-1)+F(n-2) (除了前两项) 2、斐波那契查找和斐波那契数列有什么联系? 斐波那契查找原理与前两种相似,仅仅改变了中间结点(mid)的位置,mid不再是中间或插值得到,而是位于黄金分割点附近,即mid=low+F(k-1)-1(F代表斐波那契数列) 关于F(k)-1 由斐波那契数列可知,F(k)=F(k-1)+F(k-2),那F(k)-1=(F(k-1)-1)+(F(k-2)-1)+1,所以数组长度只要满足 F(k)-1,就可以将数组分为F(k-1)-1和F(k-2)-1左右两部分,其中mid=low+F(k-1)-1 代码实现: package com.yg.search;/* @author Mu_Mu @date 2020/3/1 10:47 */ import java.util.Arrays; public class FibonacciSearch { public static int maxSize = 10; public static void main(String[]

Python 查找算法

*爱你&永不变心* 提交于 2020-03-01 21:31:25
递归查找 def bi_search_re(num_list,val): def bi_search(l, h): if(l > h): return -1 mid = (l + h) // 2 if(num_list[mid] == val): return mid ; if(num_list[mid] > val): return bi_search(l, mid - 1) else: return bi_search(mid + 1, h) return bi_search(0,len(num_list)-1) num_list = [0,1,2,3,4] print(bi_search_re(num_list,1)) print(bi_search_re(num_list,3)) 二分法查找,前提:有序 def bi_search_iter(alist,item): left, right = 0, len(alist) - 1 while(left <= right): mid = left + (right - left) // 2 #(left + right) // 2 Java或c++容易溢出 if(item < mid): right = mid -1 elif(item > mid): left = mid + 1 else: return mid

查找算法之插值查找

有些话、适合烂在心里 提交于 2020-03-01 20:13:29
package com.yg.search ; /* @author Mu_Mu @date 2020/3/1 10:08 */ public class InsertValueSearch { public static void main ( String [ ] args ) { int arr [ ] = new int [ 100 ] ; for ( int i = 0 ; i < 100 ; i++ ) { arr [ i ] = i + 2 ; } int index = insertValueSearch ( arr, 0, arr.length - 1,3 ) ; System.out.println ( "index:" + index ) ; } //插值排序需要有序序列,原理是斜率,对于每个元素间隔相同的序列一次就可以找到 //找第一个元素和最后一个元素也可以直接找到 private static int insertValueSearch ( int [ ] arr, int left, int right, int findVal ) { if ( left > right || findVal < arr [ 0 ] || findVal > arr [ arr.length - 1 ] ) { return -1 ; } int mid = left

Java编程的逻辑 (53) - 剖析Collections - 算法

六眼飞鱼酱① 提交于 2020-03-01 17:50:00
之前几节介绍了各种具体容器类和抽象容器类,上节我们提到,Java中有一个类Collections,提供了很多针对容器接口的通用功能,这些功能都是以静态方法的方式提供的。 都有哪些功能呢?大概可以分为两类: 对容器接口对象进行操作 返回一个容器接口对象 对于第一类,操作大概可以分为三组: 查找和替换 排序和调整顺序 添加和修改 对于第二类,大概可以分为两组: 适配器:将其他类型的数据转换为容器接口对象 装饰器:修饰一个给定容器接口对象,增加某种性质 它们都是围绕容器接口对象的,第一类是针对容器接口的通用操作,这是我们之前在接口的本质一节介绍的面向接口编程的一种体现,是接口的典型用法,第二类是为了使更多类型的数据更为方便和安全的参与到容器类协作体系中。 由于内容比较多,我们分为两节,本节讨论第一类,下节我们讨论第二类。下面我们分组来看下第一类中的算法。 查找和替换 查找和替换包含多组方法,我们分别来看下。 二分查找 我们在剖析Arrays类的时候介绍过二分查找,Arrays类有针对数组对象的二分查找方法,Collections提供了针对List接口的二分查找,如下所示: public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) public static <T> int