排序算法

python中自定义排序函数

余生颓废 提交于 2020-03-08 02:25:52
Python内置的 sorted()函数可对list进行排序: >>>sorted([36, 5, 12, 9, 21]) [5, 9, 12, 21, 36] 但 sorted()也是一个高阶函数,它可以接收一个比较函数来实现自定义排序,比较函数的定义是,传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。 因此,如果我们要实现倒序排序,只需要编写一个reversed_cmp函数: def reversed_cmp(x, y): if x > y: return -1 if x < y: return 1 return 0 这样,调用 sorted() 并传入 reversed_cmp 就可以实现倒序排序: >>> sorted([36, 5, 12, 9, 21], reversed_cmp) [36, 21, 12, 9, 5] sorted()也可以对字符串进行排序,字符串默认按照ASCII大小来比较: >>> sorted(['bob', 'about', 'Zoo', 'Credit']) ['Credit', 'Zoo', 'about', 'bob'] 'Zoo'排在'about'之前是因为'Z'的ASCII码比'a'小。 练习: 对字符串排序时

7-12 排序 (25分)

痞子三分冷 提交于 2020-03-07 14:35:04
给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。 本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下: 数据1:只有1个元素; 数据2:11个不相同的整数,测试基本正确性; 数据3:103个随机整数; 数据4:104个随机整数; 数据5:105个随机整数; 数据6:105个顺序整数; 数据7:105个逆序整数; 数据8:105个基本有序的整数; 数据9:105个随机正整数,每个数字不超过1000。 输入格式: 输入第一行给出正整数N(≤10 ​5 ​​ ),随后一行给出N个(长整型范围内的)整数,其间以空格分隔。 输出格式: 在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。 输入样例: 11 4 981 10 - 17 0 - 20 29 50 8 43 - 5 输出样例: - 20 - 17 - 5 0 4 8 10 29 43 50 981 代码: # include <cstdio> using namespace std ; const int MAXN = 100001 ; int N , A [ MAXN ] , TmpA [ MAXN ] ; void Msort ( int A [ ] , int TmpA [ ] , int L , int RightEnd ) ; //归并排序递归版 void

适合千万数据查询分页操作的一个通用存储过程

我的未来我决定 提交于 2020-03-07 12:45:54
适合千万数据查询分页操作的一个通用存储过程 一、引言 最近上班比较忙,所以就很少写东西了,MongoDB系列的文章也要拖后了,没办法,工作第一,没工作就没饭吃了。今天正好的有点时间,就把我最近搞得一些东西,记录下来。 在软件行业,稍微大一点的公司,相关数据的存储量就可能会很大,当我们做系统的时候,一定会使用存储过程进行分页显示,至于为什么分页显示,就不用我多说了吧。最近我在做一个系统,为了让系统支持大数据量,做了很多测试,主要是测试各种分页算法的优劣。最后,经过自己的多番测试,确定了这个存储过程。测试环境是: 硬件环境:CPU是12核的,内存是8G的大小, 软件环境:Visual Studio 2015,数据库是 Sql Server 2008 R2,数据量大概有3千万左右 ORM环境:IBatis.Net 测试效果就不贴图了,如果大家想去测试,可以自行操作,首先要说明的一点,如果针对ID主键进行分页查询,最多是300-400毫秒之间就可以把分页数据显示出来,无论是针对第一页还是最后一页显示时间都是差不多的。再者说,如果是针对其他字段的查询分页,必须针对该字段建立索引,查询速度也在毫秒之间可以完成,经过自己的多轮测试,确定了最终的存储过程的样式。当然如果针对查询的分页的字段没有索引页可以查询出来,时间就比较长了。6分钟,10分钟都有可能。由于今天只讨论存储过程,其他的就不说了

常见排序算法-----快速排序

*爱你&永不变心* 提交于 2020-03-07 11:08:20
最好时间复杂度O(nlogn) 最坏时间复杂度O(N^2) 方法一: 左右指针法: 1 /** 2 * 双指针法,将基准点设置为最左端 3 * 4 * @param arr 5 * @param left 6 * @param right 7 */ 8 public static void quicklySort(int[] arr, int left, int right) { 9 10 if (left >= right) { 11 return; 12 } 13 14 int base = arr[left]; 15 int i = left; 16 int j = right; 17 while (i < j) { 18 while (j > i && arr[j] >= base) { 19 j--; 20 } 21 while (j > i && arr[i] <= base) { 22 i++; 23 } 24 if (i < j) { 25 int temp = arr[i]; 26 arr[i] = arr[j]; 27 arr[j] = temp; 28 } 29 } 30 arr[left] = arr[i]; 31 arr[i] = base; 32 quicklySort(arr, left, i - 1); 33 quicklySort(arr, i +

C++排序中的谓语使用

纵然是瞬间 提交于 2020-03-07 04:58:46
对于C++中的谓语我第一时间就想到了C#中的委托,但两者又不尽相同,所以就写一篇笔记记录一下。 文章目录 一、什么是谓语? 二、使用谓语 一、什么是谓语? 谓语是一个可调用的表达式,其返回的结果可以作为条件的值,在C++中其实就是向算法传递函数。这和C#中的委托的概念其实是一样的,都是将函数作为参数进行传递。C++标准库中的谓语主要有两类:一元谓语和二元谓语,也就是有的算法只能向其传递具有一个参数的函数,而有的算法则可以向其传递具有两个参数的函数。 二、使用谓语 我们有时候会经常碰都要给自己创建的类型(class或struct)进行排序的问题,而在没有算法以前,我们只能自己乖乖的遍历数据进行排序。但是现在有了算法之后,我们其实只需要传递自己创建的谓语就能让我们自己创建的类型按照自己的需求进行排序,如下所示: point.h # ifndef _POINT_ # define _POINT_ # include <math.h> class point { public : double x , y , angle ; point ( double , double , double ) ; ~ point ( ) ; private : } ; point :: point ( double a = 0 , double b = 0 , double angle = 0 ) : x

Mysql之索引

…衆ロ難τιáo~ 提交于 2020-03-07 00:49:54
文章目录 索引 索引原理 索引技巧与注意事项 建立索引的原则 利用索引排序 InnoDB索引模型 联合索引 聚集索引 辅助索引 覆盖索引 索引合并 Cardinality(基数) 查看索引 Cardinality 优化器选择不使用索引的情况 MRR 验证MRR ICP 验证ICP 索引 只有当索引帮助存储引擎快速查找到记录的带来的好处大于其带来的额外工作时,索引才是有效的。对于非常小的表,大部分情况下简单的全表扫描更高效 在一个100w条数据的表中,如果某一列没有添加索引,那么每一句select语句都要随机地逐条扫描100w行数据,每次都要从中寻找0或者更多匹配的行。虽然这些数据最初是按照顺序加载的,但sql也不能理解这种顺序,它必须要处理所有行才能找到匹配的数据。添加索引并不总能自动改善所有类型的SQL查询的性能。有时候执行全表扫描反而更加高效,这取决于所要求的行数。这就是两种不同访问方式的差异,即通过随机IO操作来获取个别行的数据和使用查询索引及有序IO操作来读取所有数据。 索引除了在给定表上限制需要读取的数据外,索引的另一个主要用途就是快捷高效地在相关的表之间做Join操作。在需要Join的列上使用索引可以显著提升性能,并可以在另一个表中快速找到一个匹配的值。 优点 索引大大减少了服务器需要扫描的数据量 索引可以帮助服务器避免排序和临时表 索引可以将随机IO变为顺序IO

排序算法之二分法(折半)插入排序算法

安稳与你 提交于 2020-03-06 21:45:58
基本思想 折半插入排序的基本思想与直接插入排序一样,在插入第 i ( i ≥ 1 ) 个元素时,前面 i − 1 个元素已经排好序。差别在于寻找插入位置的方法不同。折半插入排序是採用折半查找法来寻找插入位置的。 折半查找法的基本思路是:用待插元素的值与当前查找序列的中间元素的值进行比較,以当前查找序列的中间元素为分界,确定待插元素是在当前查找序列的左边还是右边,假设是在其左边。则以该左边序列为当前查找序列。右边也相似。依照上述方法,递归地处理新序列。直到当前查找序列的长度小于1时查找过程结束。 代码 //待排数据存储在数组a中。以及待排序列的左右边界 public void BinaryInsertSort(int[] a, int left, int right) { int low, middle, high; int temp; for (int i = left + 1; i <= right; i++) { temp = a[i]; low = left; high = i - 1; while (low <= high) { middle = (low + high) / 2; if (a[i] < a[middle]) high = middle - 1; else low = middle + 1; } for (int j = i - 1; j >= low; j

二分法排序

谁都会走 提交于 2020-03-06 21:44:06
#include<stdio.h> #define MAXNUM 100 typedef int KeyType; typedef int DataType; typedef struct { KeyType key; /* 排序码字段 */ /*DataType info; 记录的其它字段 */ } RecordNode; typedef struct { int n; /* n为文件中的记录个数,n<MAXNUM */ RecordNode record[MAXNUM]; } SortObject; void binSort(SortObject * pvector) { /* 按递增序进行二分法插入排序 */ int i, j, left, mid, right; RecordNode temp; RecordNode *data = pvector->record; for( i = 1; i < pvector->n; i++ ) { temp = data[i]; left = 0; right = i-1; /* 置已排序区间的下、上界初值 */ while (left <= right) { mid = (left + right)/2; /* mid指向已排序区间的中间位置 */ if (temp.key < data[mid].key) right = mid

二分法排序

戏子无情 提交于 2020-03-06 21:41:22
算法思想简单描述: 在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们 中间的那个元素比,如果小,则对前半再进行折半,否则对后半 进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间 的所有元素后移,再把第i个元素放在目标位置上。 二分法排序最重要的一个步骤就是查找要插入元素的位置,也就是要在哪一个位置上放我们要准备排序的这个元素。当我们查找到位置以后就很好说了,和插入排序一样,将这个位置以后的所有元素都向后移动一位。这样就实现了二分法排序。  然后是怎么查找着一个位置呢,就是不断的比较已排序的序列中的中间元素和要排序元素,如果大于的话,说明这个要排序的元素在已排序序列中点之前的序列。 public static void DichotomySort(int[] array) { for (int i = 0; i < array.Length; i++) { int start, end, mid; start = 0; end = i - 1; mid = 0; int temp = array[i]; while (start <= end) { mid = (start + end) / 2; if (array[mid] > temp)//要排序元素在已经排过序的数组左边 { end = mid - 1; } else { start =

快速排序

 ̄綄美尐妖づ 提交于 2020-03-06 12:32:34
快速排序(QuickSort) 划分的关键是要求出基准记录所在的位置pivotpos,编程时候的关键点 快速排序: 既然能把冒泡KO掉,马上就激起我们的兴趣,tnd快排咋这么快,一定要好好研究一下。 首先上图: 从图中我们可以看到: left指针,right指针,base参照数。 其实思想是蛮简单的,就是通过第一遍的遍历(让left和right指针重合)来找到数组的切割点。 第一步:首先我们从数组的left位置取出该数(20)作为基准(base)参照物。 第二步:从数组的right位置向前找,一直找到比(base)小的数, 如果找到,将此数赋给left位置(也就是将10赋给20), 此时数组为:10,40,50,10,60, left和right指针分别为前后的10。 第三步:从数组的left位置向后找,一直找到比(base)大的数, 如果找到,将此数赋给right的位置(也就是40赋给10), 此时数组为:10,40,50,40,60, left和right指针分别为前后的40。 第四步:重复“第二,第三“步骤,直到left和right指针重合, 最后将(base)插入到40的位置, 此时数组值为: 10,20,50,40,60,至此完成一次排序。 第五步:此时20已经潜入到数组的内部,20的左侧一组数都比20小,20的右侧作为一组数都比20大, 以20为切入点对左右两边数按照