插入排序

插入排序

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-30 04:51:09
插入排序 算法思想 插入排序是一个特别好理解的排序算法,这里举一个打牌的例子说明一个工作原理。在开始摸牌的时候,我们手里是没有扑克牌的,当摸第一个张牌的时候,我们先放在手里,当有第二张牌的时候,当它比我们手里的牌大,就放在右边,当比手里的牌小就放在左边,即升序排序(当然也可以降序);当第三张牌的时候,就选择合适的位置查进去,使得手里的牌是有序的。那么当整个扑克摸完的时候,我们手里的牌也是有序的。排序算法就是这个原理,手里的牌相当于已经排好序的数字,还没有摸的牌相当于待排序的数字。 插入排序算法的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 算法步骤: 从第一个元素开始,表示该元素是排好序的 取下一个元素cur,在排好序的序列上从后向前扫描,记录为temp 如果temp大于cur,将temp的位置向前移动一个位置 重复步骤3,直到找到temp小于或者等于cur 将新元素插入到当前位置 重复步骤2~5 下面通过一个动画看一下插入排序的排序过程 通过上述的过程,直接插入排序是一种稳定的排序算法,时间复杂度为 O ( n 2 ) O(n^2) O ( n 2 ) ,即外层需要遍历每一个元素作为未排序的数字,内层需要遍历需要插入的位置,每个循环的最坏次数为 n n n 次;每次交换都需要定义一个临时变量作为数据交换,额外的空间复杂度为 O (

算法提高 插入排序

非 Y 不嫁゛ 提交于 2020-01-29 23:04:00
算法提高 插入排序 排序,顾名思义,是将若干个元素按其大小关系排出一个顺序。形式化描述如下:有n个元素a[1],a[2],…,a[n],从小到大排序就是将它们排成一个新顺序a[i[1]]<a[i[2]]<…<a[i[n]] i[k]为这个新顺序。 插入排序,顾名思义,是通过插入操作完成排序。其直觉和方法来源于打牌时安排牌的方法。每次摸起一张牌,你都会将其插入到现在手牌中它按顺序应在的那个位置。插入排序每一步都类似这个摸牌过程。比如现在有整数数组:{3, 1, 5, 4, 2} 第一步:插入3 得到新序列{3} 第二步:插入1 得到新序列{1 3} 第三步:插入5 得到新序列{1 3 5} 第四步:插入4 得到新序列{1 3 4 5} 第五步:插入2 得到新序列{1 2 3 4 5} 为了看程序中如何完成插入过程,我们以第五步为例: 初始时:1 3 4 5 2 将2存入临时变量tmp 将下标j指向2之前的元素5,然后根据tmp和a[j]的大小关系决定该元素是否应该后移。如果a[j]>tmp,则将a[j]后移到a[j+1],序列变成1 3 4 5 5。 将下标j前移 判断a[j]>tmp,后移a[j]到a[j+1],得到1 3 4 4 5 将下标j前移 判断a[j]>tmp,后移a[j]到a[j+1],得到1 3 3 4 5 因为a[j]<=tmp,所以将tmp放回a[j+1],得到

排序算法(插入排序、冒泡排序、选择排序、希尔排序)

被刻印的时光 ゝ 提交于 2020-01-29 21:43:50
今天介绍一些排序算法,作为算法中最基础的部分,掌握各种排序算法以及指导各种排序算法的复杂度是有必要的。 插入排序 顾名思义,插入排序就是首先在待排序的数组中挑选出一个数,然后向前看,找到它所在的合适位置,将该位置后面的数都后移一次,再将选取的数插进去就行。其原理就跟咱们打扑克插牌是一样的。 以下面五个无序的数字为例: 2 3 1 5 4 第一次插入:2 3 1 5 4(3比2大,不用动) 第二次插入:1 2 3 5 4(将1插到第一位,2,3后移) 第三次插入:1 2 3 5 4(5前面没有比5大的,不动) 第四次插入:1 2 3 4 5(4插到第四位,5后移) void charupaixu ( int * a , int n ) { for ( int i = 1 ; i < n ; i ++ ) { int x = a [ i ] ; int j = i - 1 ; while ( j >= 0 && a [ j ] > x ) { a [ j + 1 ] = a [ j ] ; j -- ; } a [ j + 1 ] = x ; } } 算法复杂度为O(N²) 冒泡排序 冒泡排序这个名字期的非常生动,相信你看完下面的解释就会明白它为什么叫这个名字。 冒泡排序与插入排序不同,插入排序是选取一个对象与多个对象进行比较,而冒泡排序是两个元素互相比较,例如给出一串无序数组:2 3

希尔排序

久未见 提交于 2020-01-27 20:21:54
一:什么是希尔排序 希尔排序基于插入排序,并添加了新特性,提高效率. 二:插入排序的缺陷 加入一个很小的数值排在最末尾,如果需要正确排序,则需要将所有的数据都向右移动才可以将小的数据排到前面 缺陷: 移动次数太多 三:希尔排序的优点 加大排序中元素之间的间隔,对这些间隔的元素进行插入排序,使数据可以大幅度移动,当完成间隔排序后,希尔排序会减少间隔之间的元素再进行排序,依次进行下去 四:间隔计算 间隔h的初始值为1,通过 h = 3*h + 1 来计算循环,直到该间隔大于数组的大小时停止.最大间隔为不大于数组大小的最大值 五:间隔减少 公式: h = (h -1)/3 六:代码实现 public class ShellSort { public static void main ( String [ ] args ) { long [ ] arr = { 3 , 4 , 7 , 2 , 1 , 0 , 8 } ; sort ( arr ) ; System . out . println ( Arrays . toString ( arr ) ) ; } //希尔排序 public static void sort ( long [ ] arr ) { //初始化间隔 int h = 1 ; //计算最大间隔 while ( h < arr . length / 3 ) { h =

排序算法——插入排序

自作多情 提交于 2020-01-26 06:09:12
插入排序 拥有一个无序的数组,我们只需先拿一个数(一般拿第一个),把它先当作一个有序的数组。然后把这个无序数组中其它数分别插入到已经有序的数组中即可。 代码构造思路 :首先得考虑要用什么数据结构,是链表还是顺序表。在下面的代码中,我使用的是顺序表,其实就是普通的数组。然后因为我拿第一个数做为已经有序的数组,剩下只需要把其它在无序数组中的数,插入到有序数组中即可,所以外循环其实只需要循环 n-1 次。而每次循环的 nums[i] 其实就是代rug表当前要插入的数,然后构造内循环,内循环所循环的其实就是已经有序的数组,从尾到头进行遍历,至于为什么是从尾到头,当然是因为在顺序表中执行插入操作,不管插入到哪里,插入位置后面的数组自然都需要往后移一个位置,而在插入排序中,从尾到头的遍历的时候,在比较的同时,也在移动数组中数的位置。就是需要插入的数需要排在当前遍历到的有序数组的数的前面,自然需要把这个数后移,而因为是从尾到头的遍历,所以每一次的比较的位置不是正确的位置,都会把当前有序数组的数往后一位,直到找到合适的位置,进行插入。而这个合适的位置就是 nums[j + 1] = insertNum 。 时间复杂度 : 平均情况 最好情况 最坏情况 O ( N 2 ) O(N^2) O ( N 2 ) O ( N ) O(N) O ( N ) O ( N 2 ) O(N^2) O ( N 2 )

算法导论第7章习题

纵然是瞬间 提交于 2020-01-26 00:34:46
做题要猜出题目的意图。 7.1-1 略 7.1-2 r-1, add if q=r-1, then $q = \lfloor (p+r)/2 \rfloor$。这说明元素全都一样的时候,quicksort伤不起。worst-case了,要$\Theta(n^2)$了。快排弱点1. 7.1-3 pivot要比较所有的数组元素,自然是n 7.1-4 PARTITION中Line4的<= changed to >= 7.2-1 T(n)=T(n-1)+\Theta(n)=T(0)+n*\Theta(n)=\Theta(n^2) 7.2-2 同7.1-2 7.2-3 These exercises demonstrate the weakness of the original quicksort. It’s the worst case. T(n) = T(n-1)+\Theta(n)=\Theta(n^2)。快排弱点2. 7.2-4 银行喜欢时间排序,用户喜欢支票号排序。这道题又说明了在nearly sorted list中,插入排序beat了快排。快排弱点3.因为用户使用多张支票是连号的,所以在一个时间段内,顶多是这几张支票打乱了顺序。而不是一天24小时之内所有的支票全部乱序。所以这个序列是差不多有序的。如果n个用户每次使用k张支票,插入排序最多需要O(nk)时间,如果k=1

排序算法-插入排序

巧了我就是萌 提交于 2020-01-24 12:46:49
一、插入排序(InsertSort) 插入排序从第二个数开始,拿出第二个数进行向前插入排序,一直到最后一个数向前做插入排序。算法稳定。 插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。最好的时间复杂度是O(n),最坏也就是平均是O(n^2) 二、图解 对于一串数字(3,5,2,1,4,10)进行插入从小到大排序,如下图演示 三、算法分析 /** * 插入排序 * 1、确定插入排序的数,从第二个开始选择 * 2、选择插入排序的数,保存为num * 3、计算num前一个数的索引 * 4、进行检查,如果num小于前面的数,则将前一个数往后移,若比前一个数大,则结束此次循环 * 5、结束时的位置保存num * @param arr */ public static void insertSort(int[] arr) { for (int i = 1; i < arr.length; i++) { //选择插入排序的数,保存为num int num = arr[i]; //计算num前一个数的索引 int preIndex = i - 1; for (; preIndex >= 0; preIndex--) { //进行检查,如果num小于前面的数,则将前一个数往后移,若比前一个数大,则结束此次循环 if (num < arr[preIndex]) arr[preIndex +

【读书笔记】理解基本排序算法

故事扮演 提交于 2020-01-23 03:40:15
开始日期:2018/07/23 前言 近段时间一直在阅读《数据结构与算法JavaScript描述》这本书,重新学习下算法。算法是作为一个程序员的基本素养,还是掌握一些基本的算法的,譬如排序算法。排序算法又分为基本排序算法和高级排序算法,以排序的效率来划分。以下的冒泡排序就是基本排序算法,最慢的排序算法之一。 冒泡排序 最慢的排序算法之一,数据值会像气泡一样从数组的一端飘向另一端。之所以会产生这种现象是因为算法会多次在数组中移动,比较相邻的数据,假设按升序排序,则当左侧值大于右侧值时将它们进行互换。 示例代码: function bubbleSort(arr){ var length = arr.length; // 数组交换方法 var swap = function(arr,index1,index2){ var temp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = temp; } // 外循环则表示相邻比较的次数,比较一次后,最大的数会移向最右侧,则次数减一,进行下一轮循环 for(var outer = length; outer >= 2; --outer){ // 内循环则表示从第一个数值开始相邻比较,一直到最后一个 for(var inner = 0; inner< outer; inner){ if

插入排序

一曲冷凌霜 提交于 2020-01-22 05:54:52
插入排序 两层循环。 内层循环,将元素与前面有序区元素比较,通过通过不断后移,腾出本次要插入的位置。 #include<iostream> using namespace std; void insertSort(int a[],int n) { for(int i=1;i<n;i++) { int temp=a[i]; int j; for(j=i-1;j>=0;j--) { if(a[j]>temp) a[j+1]=a[j]; else break; //退出内层循环 } a[j+1]=temp; } } int main() { int a[6]={3,2,6,4,1,5}; insertSort(a,6); for(int i=0;i<6;i++) { cout<<a[i]; } return 0; } 来源: CSDN 作者: 康斯但丁丶 链接: https://blog.csdn.net/OpenStack_/article/details/103746081

【前端算法3】插入排序

主宰稳场 提交于 2020-01-20 15:11:25
/** 插入排序 * 同一个数组,从第一个元素开始,该元素可以认为已经被排序 * 取出下一个元素,在已经排序的元素序列中从后向前扫描 * 如果当前值大于前一个值 让后一个值等于前一个值 否则跳出当前循环 * * 注意点:(当前值大于前一个值 让后一个值等于前一个值)只交换了一半,while外层还需要交换另外一半 * **/ function insertSort(arr) { let i = 1; let j,key; for (i; i < arr.length; i++) { j = i; key = arr[j]; // while 是 将目标值从后往前 找插入的位置 while (--j > -1) { // 如果 j = -1 则目标值比所有的已排序元素都小 // 如果当前值大于前一个值 if (arr[j] > key) { arr[j+1] = arr[j]; // 让后一个值等于前一个值 } else { break; // 否则跳出当前循环 } } arr[j+1] = key; // 与冒泡同理,让前一个值等于后一个值(两个值交换了位置) } return arr; } let arr = [2, 8, 4, 5, 3, 7, 6]; let res = insertSort(arr); console.log(res); 来源: https://www