插入排序 Insertion-sort

---恢复内容开始---

插入排序

经典显示(参照算法导论)

一副扑克牌放在桌面上 花色朝下,每次从桌面上拿去最上面的一张 ,放入自己手中的牌中的正确位置,(每次都是对手中的牌排序,并且每次拿去桌面上的牌时,手中的牌已经排序好,当桌上的牌没有时,所有的排序都已经排序好.   其中注意点:将后面一张牌与前一张比如果小于就交换位置。 办法二 【最佳方法】将最后一张牌与 for循环下面的每个元素比A[i],若小于就向后移一位A[i+1] = A[i], 但是刚拿过的牌 j 必须要付给一个临时变量来保存其中的值。否则会被前面的一位给覆盖掉。再讲tmp放入合适位置)

术语:

循环不变式:手中已经排好序的A[1 .... j-1]表示循环不变式

循环不变式:在循环过程中的状态值:

初始化:内循环的之前为真,即 循环第一次迭代之前为真                 证明 a[i]为a[0],只有一个元素。故为真

保持:如果循环的某次迭代之前为真 ,那么 下次迭代之前,它仍为真   证明 假设 a[1 ... j-1 ]为真, 下一个插入元素找到合适位置,故a[1 .... j]也为真

终止:当循环终止时,不变式为仍为真               证明 终止条件 j>A.length 终止时 已经排好序 故为真  保持真确

核心模板

insertion-sort(A)                        代价      次数

for 2 to A.length                            c1     n

  key=A[j]                           c2           n-1

  //insett A[j] into the sorted sequence A[1 ...... j-1]    

  // 插入A[j]到已经排好序的序列A[1 .... j-1]

  i = j- i                             c3           n -1

  while i>0 and A[j]>key                    c4           2+3+4+5+.......+n = n(n+1)/2-1

    A[i+1] = A[i]                       c5           2+3+4+.......+n-1 = n(n-1)/2

    i = i - 1                         c6            n(n-1)/2

  A[i+1] = key                         c7            n-1

 

Java核心代码

//

for(int i=0; i<a.length; i++){

  //对前 i 张进行排序,每次内循环中 i 的值是不变的

  for(int j=i-1; j>0; i--){

    if(a[j+1]<a[j]){  //第一个j+交换1 的值就是a[i] 的值 每次都和前一个作比较 如果小于 就交换

      swap(i,j);

    }else{

      break;  

    }

  }

}

public void swap(int i,int j){

  int tmp = a[j];

  a[j] = a[i];

  a[i] = a[j];

}

//正确的

for(int i=0; i<a.length; i++){

  //对前 i 张进行排序,每次内循环中 i 的值是不变的

  int tmp = a[i]

  int j= i-1;

  for(j; j>0; j--){

    if(a[j]>tmp){

      a[j+1] = a[j];

    }else{

      a[j+1] = tmp;

    }

  }

}

分析算法 :分析运行时间(影响 运行性能的因素:规模, 以及已排序程度 )

    如上图 模板中的运行时将总和

  T(n)= c1n + c2(n-1) + c3(n-1) + c4(n(n+1)/2-1)  + c5(n(n-1)/2)  + c6(n(n-1)/2) +c7(n-1)

    =(c4 + c5 + c6 )n*2 +  (c1 + c2 + c3 + c4/2 - c5/2 - c6/2 +c7)n - (c2 + c3 + c4 + c5)

  最好情况  a[i]>a[j].   所以 对于while 循环体内 只执行一次  c4

故 T(n) =  (c1 + c 2 + c3 + c4 + c7)n - (c2 + c3 + c4 +c8) 为线性函数 故时将复杂度相当于 O(n)[读作 theta n ]

  最坏情况: 倒序 (算法运行的最长时间)【最坏情况。数据库中对缺失信息的检索。最坏情况就会出现。所以在数据库中就会经常出现最坏情况】

  平均情况:平均情况 往往与最坏情况 大致一致 。往往都是同种性质的同种维度的 增量函数

时间复杂度: 【参照 xingoo博客】

如果排序的数组是正序的,那么时间复杂度相当于O(n),

而如果排序是随机的,时间复杂度相当于O(n^2/4).

倒置的时间复杂度是最高的,O(n^2).

时间: 2024-10-10 14:43:08

插入排序 Insertion-sort的相关文章

经典排序算法 – 插入排序Insertion sort

经典排序算法 – 插入排序Insertion sort  插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕. 插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序,折半插入排序留到“查找”内容中进行.   图1演示了对4个元素进行直接插入排序的过程,共需要(a),(b),(c)三次插入. 以下代码仅供参考,欢迎指正 /// <summary> /// 插入排序 /// </summary> /// <param na

排序算法一:插入排序(Insertion sort)

最近从网易公开课在看麻省理工学院的公开课<算法导论>,感觉还不错,接下来几篇文章所示学习日记了,不准备对算法细节做过多描述,感兴趣的可以自己去看. 文章分几篇讲经典排序算法,直接上代码,根据结果对算法性能有个直观了解.本篇先说插入排序(insertion sort). (一)算法实现 1 protected void sort(int[] toSort) { 2 if (toSort.length <= 1) { 3 return; 4 } 5 for (int i = 1; i <

【 python 学习笔记 -- 数据结构与算法 】插入排序 Insertion Sort

[插入排序]:每次保证列表最左端子序列是排好顺序的,然后取下一个元素,扫描其左端的子序列,将其中大于目标元素的元素右移一个位置,直到找到合适的位置将目标元素插入子序列中.逐步增大排序完成的sublist的长度,最终完成整个列表的排序 算法思路如下: 1. 列表最左边第一个元素认为已经排序好了 2. 取下一个元素(目标元素),在它前面已经排序完成的子序列中从后向前扫描 3. 如果子序列中被扫描的当前元素大于目标元素,则将当前元素右移一个位置 4. 重复第3步,直到被扫描的元素小于或等于目标元素 5

插入排序Insertion sort

插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕. 插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序. #include <iostream> using namespace std; static void insert_sort(int unsorted[], int length) { for(int i=1; i<length; i++) { int key = unsorted[i]; int j = i - 1;

基础算法之插入排序Insertion Sort

原理 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间.相信大家都打过扑克牌,很好理解. 例子 将数组[5,6,3,1,8,7,2,4]进行从小到大排序 排序步骤: 从第一个元素开始,该元素可以认为已经被排序 取出下一个元素,在已经排序的元素序列中从后向前扫描 如果该元素(已排序)大于新元素,将该元素移到下一位置

程序算法艺术与实践经典排序算法之Insertion Sort

插入排序(Insertion Sort)的基本思想是每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止. 基本思想与伪代码 经过j-1遍处理后,A[1..j-1]己排好序.第j遍处理仅将A[j]插入L[1..j-1]的适当位置,使得A[1..j]又是排好序的序列.要达到这个目的,我们可以用顺序比较的方法.首先比较A[j]和A[j-1],如果A[j-1]≤ A[j],则A[1..j]已排好序,第i遍处理就结束了:否则交换A[j]与A[j-1]的

直接插入排序(Straight Insertion Sort)的C语言实现

原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 直接插入排序(Straight Insertion Sort)的基本思想是将新记录插入到已经排好序的有序表中,初始有序表只有无序表的第一个数据,依次对无序表每个数据进行直接插入排序,从而得到了有序表,具体步骤为 若新记录<有序表高位l.r[j],则设置哨兵 有序表后移,j+1=j 重复第2步,直至新纪录>=有序表中的j记录,则j+1就是要插入的位置 从而得到一个新的.记录数增加1的有序表

折半插入排序(Binary Insertion Sort)的C语言实现

原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 折半插入排序(Binary Insertion Sort)的基本思想是将新记录插入到已经排好序的有序表中,初始有序表只有无序表的第一个数据,依次对无序表每个数据进行折半插入排序,从而得到了有序表,具体步骤为 先将记录存在L.r[0]中,low=有序表低位下标,high=有序表高位下标 若low<=high,就将L.r[0]与mid=(low+high)/2位的数据比较,如果L.r[0]>

2-路插入排序(2-way Insertion Sort)的C语言实现

原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 2-路插入排序(2-way Insertion Sort)的基本思想: 比fisrt小的元素,插入first前面: 比final大的元素,插入final后面, 比fisrt大且比final小的元素插中间 演示实例: C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 1 #include <stdio.h> 2 #define LEN 6 3 4 typedef float

leetcode——Insertion Sort List 对链表进行插入排序(AC)

Sort a linked list using insertion sort. class Solution { public: ListNode *insertionSortList(ListNode *head) { if(head == NULL || head->next == NULL) return head; ListNode *result; result->val = INT_MIN; result->next = NULL; ListNode *cur=head,*