插入排序

干货 | 十大经典排序算法最强总结(内含代码实现)

不羁岁月 提交于 2019-12-03 09:59:36
干货 | 十大经典排序算法最强总结(内含代码实现) 一、算法分类 十种常见排序算法可以分为两大类: 比较类排序: 通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。 非比较类排序: 不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。 二、算法复杂度 三、算法相关概念 稳定: 如果a原本在b前面,而a=b,排序之后a仍然在b的前面。 不稳定: 如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。 时间复杂度: 对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。 空间复杂度: 是指算法在计算机 内执行时所需存储空间的度量,它也是数据规模n的函数。 四、具体说明 1、冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,

算法第二章作业

匿名 (未验证) 提交于 2019-12-03 00:13:02
在这一年的打题过程中,从最开始的手敲冒泡排序到现在一直用STL里的sort,排序算法使用的频率可以说是非常高的了,而且各种排序算法的思想和有关的一些数据结构也会经常用到,但之前一直听说sort是基于快排的,就会有疑问――堆排序的最坏最好复杂度都是nlogn,而快排的最坏复杂度是n 2 ,为什么不用堆排呢。国庆这几天断断续续地看完了老师给的博客之后终于明白了这个问题,而且更加深入地了解了sort函数对快排的极致优化。 从平均时间上来说,堆排的时间常数要比快排大,因为堆排会让某些数据出现很多大幅度的无效的移动,而快排则是将每个元素快速地移动到最终位置上或是附近,然后进行小范围的移动,详见 https://www.zhihu.com/question/20842649 http://mindhacks.cn/2008/06/13/why-is-quicksort-so-quick/ 那么std::sort又是怎么实现来尽量避免快排的最坏情况呢,这篇博客给出了详细的解答 http://feihu.me/blog/2014/sgi-std-sort/ 为了让自己看的时候不至于被各种函数名弄晕,做了个图辅助一下 基于个人的理解 __introsort_loop这个函数的主体部分就是快速排序的部分,但它与一般的快排不一样的是,为了尽量减少枢轴为极值引起的递归恶化,它选取了开头、中间

插入排序算法的思想

匿名 (未验证) 提交于 2019-12-02 23:59:01
原始数组:a=[8,6,2,3,7,9,1]; 要求升序。 step1:因为8是第一个,所以8固定不动,让6和8比,因为6小于8,所以,6和8交换位子,数组变为6,8,2,3,7,9,1。这1轮比较完毕。 step2:将2与它的前一个,也就是8比,因为2小于8,所以2和8交换位子,数组变为6,2,8,3,7,9,1。 再将2与6比,比完之后2与6交换位子,数组变为2,6,8,3,7,9,1。这一轮比较完毕。 step3:将3与8比,所以3与8交换位子,数组变为2,6,3,8,7,9,1。 将3与6比,所以3和6交换位子,得到2,3,6,8,7,9,1。 将3与2比,因为3不比2小,所以位子不变,跳出循环,跳出这一轮比较。 step4:以此类推…… 代码为 1 for ( int i = 1 ; i < n ; i ++) { //外层循环 ,整个过程其实就是在为a[i]寻找合适的插入位子 2 for ( int j = i , j > 0 ; j --) { //内层循环,因为是倒回去比较,所以是减减 3 if ( a [ i ]< a [ j ]) 4 swap ( a [ i ], a [ j ]); //swap函数的作用就是交换位子 5 else break 6 } 7 } 如果想把代码的行数写少点,可以把上述代码修改一下, 1 for ( int i = 1 ; i <

几大排序的稳定性

匿名 (未验证) 提交于 2019-12-02 23:49:02
以前看人利用口诀记忆排序的稳定性:考研好痛苦,一堆(堆排序)专业课,情绪不稳定(不稳定排序),快(快速排序)来选(选择排序)一些(希尔排序)朋友聊聊天吧,剩下的都是稳定的。 感觉不错。。。。。。 接下来是八大排序总结 : (1)冒泡排序 冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。 1 void bubbleSort(int a[], int low, int high){//[low,high) 2 while(low < (high = bubble(a, low, high)));//逐趟扫描,直至全部有序 3 } 4 5 6 7 int bubble(int a[], int low, int high){ 8 int last = low; 9 while(++low<high) 10 if(a[low-1]>a[low]){ 11 swap(a[low-1],a[low]); 12 last = low;//找到上次最后一次发生交换的位置 13 } 14 return last; 15 }/

sort(()=&gt;{return Math.random()-0.5)}乱序数组不准确

匿名 (未验证) 提交于 2019-12-02 23:48:02
/*--> */ /*--> */ /*--> */ /*--> */ /*--> */ Ϊʲô sort(() =>{return Math.random() -0.5) }乱序数组不准确。(注意结合插入排序原理来理解) @1、 chrome浏览器对于数组长度 10以内为插入排序。反之则快速排序和插入排序混合 @2、所以,对于[ 1, 2, 3] 第一此比较对 1和 2就行排序,可能为正序也可能为倒序,所以两种可能一种生成[ 1, 2, 3]一种[ 2, 1, 3]。 3和上述两种数组的第二个元素进行比较,也有两种排序可能,倒序和正序,如果为正序则不变排序完成。如果为倒序则需要和 1或者 2交换位置,假设第一次排序生成为[ 1, 2, 3],生成[ 1, 3, 2]此时插入排序并未完成。所以继续和 1进行比较,又有两种情况。生成[ 3, 1, 2]或者[ 1, 3, 2]。 所以到[1 ,2 ,3 ]概率为1/2*1/2=25% 。 数组乱序有六种可能,所以一种应该平均为 100/6。所以这显然不对。

冒泡、选择、插入排序 不带对数器版本

匿名 (未验证) 提交于 2019-12-02 23:48:02
1 package com . aixuexi . contact ; 2 3 public class BubbleSort { 4 public static void main ( String [] args ) { 5 int arr [] = new int [] { 985 , 2 , 6 }; 6 //冒泡 O(N*N) 7 for ( int end = arr . length - 1 ; end > 0 ; end --) { 8 for ( int i = 0 ; i < end ; i ++) { 9 if ( arr [ i ] > arr [ i + 1 ]) { 10 int tmp = arr [ i ]; 11 arr [ i ] = arr [ i + 1 ]; 12 arr [ i + 1 ] = tmp ; 13 } 14 } 15 } 16 17 //选择 O(N*N) 18 for ( int i = 0 ; i < arr . length - 1 ; ++ i ) { 19 20 int Indexmin = i ; 21 22 for ( int j = i + 1 ; j < arr . length ; ++ j ) { 23 Indexmin = arr [ j ] < arr [ Indexmin ] ? j :

插入排序

匿名 (未验证) 提交于 2019-12-02 23:44:01
package com.cisco.www.sort;/** * 插入排序 */public class InsertSort { public static void insertSort(int[] arr){ if(arr==null||arr.length<2){ return; } for(int i = 1 ; i<arr.length;i++){ for(int j = i-1;j>=0&&arr[j]>arr[j+1];j--){ swap(arr,j,j+1); } } } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i]=arr[j]; arr[j]=temp; }}

插入排序

匿名 (未验证) 提交于 2019-12-02 23:43:01
package com.cisco.www.sort;/** * 插入排序 */public class InsertSort { public static void insertSort(int[] arr){ if(arr==null||arr.length<2){ return; } for(int i = 1 ; i<arr.length;i++){ for(int j = i-1;j>=0&&arr[j]>arr[j+1];j--){ swap(arr,j,j+1); } } } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i]=arr[j]; arr[j]=temp; }}

详解插入排序算法

匿名 (未验证) 提交于 2019-12-02 23:03:14
思路: 将数组的0到0位置弄有序,再将0到1位置弄有序,再将0到2位置弄有序,最后将0到n-1位置弄有序,这个数组也就有序了。 我们假设有一个数组,2, 3, 4, 1, 3。0到0上的位置就只有一个数字2,有序,不用做改变。 0到1有序,0到2有序。好,现在到0到3了。 现在是0到4了。 代码: import java.util.Scanner; public class InsertSort { //插入排序算法核心 public static void insert(int a[]) { if(a == null || a.length < 2) { return; } for(int i = 1; i < a.length; i++) { for(int j = i - 1; j >= 0 && a[j] > a[j + 1]; j--) { swap(a, j, j + 1); } } } //将数组中的两个数交换 public static void swap(int a[], int i, int j) { int temp; temp = a[i]; a[i] = a[j]; a[j] = temp; } public static void main(String args[]) { //输入数组中有几个数 System.out.print("请输入一个正整数:"

Java俩种形式实现插入排序法

匿名 (未验证) 提交于 2019-12-02 21:53:52
排序的重要性使得大家总是走在寻找新方法的路上,冒泡排序->选择排序->插入排序三种方法见证了这一过程,这三种简单排序在实际应用中的使用率也是比较大的,当然也是我们学习高级排序的一个基础。 ------------------------ 什么是插入排序 ―― 局部有序 的群体中去。下面通过一个简图来说明一下: 黑色空心箭头 由左向右遍历数组,每移动到一个位置便找到一个将要进行插入操作的元素( 绿色椭圆, 由于其所在位置后续会被覆盖,所以需将其值保存在临时变量temp中 ),通过与 黑色空心箭头 经过的元素进行比较,并将比此操作元素( 绿色椭圆 )大的元素依次向右侧移动,依次类推直到找到小于此操作元素 ( 绿色椭圆 ) 的位置,此时所有大于操作元素( 绿色椭圆 )的元素都已向后移动了一位并空出一个位置留给操作元素( 绿色椭圆 ),最后只需将操作元素( 绿色椭圆 )插入到这个空位置即完成了一次插入排序 (此操作过程的操作域为 黑色虚线 左侧部分,而这个操作域也变成了下一次操作的局部有序群体) 。然后 黑色空心箭头 继续向右侧移动,且每移动一次就重复一遍上边的过程,直至遍历完所有元素即完成了所有数据的插入排序。 实现原理 ―― 继续盗用《Java数据结构和算法》一书中的图。 但个人而言,本人在 什么是插入排序 中所叙述的更能体现插入排序的原理。 实现源码 ―― import java