插入排序之算法

一、定义

往有序的数组中插入一个新元素。

二、算法思想

把要排序的数组分为了两个部分,一部分是数组的全部元素(除去待插入的元素),另一部分是待插入的元素;
先将第一部分排序完成,然后再插入这个元素。其中第一部分的排序也是通过再次拆分为两部分来进行的。

三、具体实现
1、直接插入排序
将待排序的元素按照大小顺序,依次插入到一个已经排好序的数组之中,直到所有的元素都插入进去。
由于直接插入排序每次只移动一个元素的位置,并不会改变值相同的元素之间的排序,因此它是一种稳定排序。

function insertSort(arr) {
  var len = arr.length,     // 数组的长度
      current,             // 当前比较的值
      i,                  // 未排序部分的当前位置
      j;                 // 已排序部分的当前位置
  for(i=0; i < len; i++) {
    // 储存当前位置的值
    current = arr[i];
    /*
     * 当已排序部分的当前元素大于current,
     * 就将当前元素向后移一位,再将前一位与current比较。
     */
    for(j=i-1; j > -1 && arr[j] > current; j--) {
      arr[j+1] = arr[j];
    }
    arr[j+1] = current;
  }
  return arr;
}
console.log(insertSort([3,115,9,2,11,6,3,19]));

2、折半插入排序
比较中间值与待插入元素的大小,折半插入排序每次交换的是相邻的且值为不同的元素,它并不会改变值相同的元素之间的顺序,因此它是稳定的。明显减少了查询的次数,但是数组元素移动的次数却没有改变。

function binaryInsertSort(arr){
  var current, i, j, low, high, mid;
  for(i = 1; i < arr.length; i++){
    low = 0;
    high = i - 1;
    current = arr[i];

    while(low <= high){            //步骤1&2:折半查找
      mid = (low + high)>>1;
      if(current >= arr[mid]){//值相同时, 切换到高半区,保证稳定性
        low = mid + 1;        //插入点在高半区
      }else{
        high = mid - 1;       //插入点在低半区
      }
    }
    for(j = i; j > low; j--){     //步骤3:插入位置之后的元素全部后移一位
      arr[j] = arr[j-1];
    }
    arr[low] = current;        //步骤4:插入该元素
  }
  return arr;
}
console.log(binaryInsertSort([3,115,9,2,11,6,3,19]));

3、希尔排序
缩小增量排序,实质就是分组插入排序。先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
单次直接插入排序是稳定的,它不会改变相同元素之间的相对顺序,但在多次不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,可能导致相同元素相对顺序发生变化。因此,希尔排序并不稳定。

function shellSort(arr) {
  let len = arr.length,
    current,
    gap = 1;
  while(gap < len / 3) {
    gap = gap * 3 + 1;
  }
  for(gap; gap > 0; gap = Math.floor(gap / 3)) {
    for(let i = gap; i < len; i++) {
      current = arr[i];
      for (var j = i - gap; j >= 0 && arr[j] > current; j -= gap) {
        arr[j + gap] = arr[j];
      }
      if(j + gap !=i){
        arr[j + gap] = current;
      }
    }
  }
  return arr;
}
console.log(shellSort([3,115,9,2,11,6,3,19]));

四、效率分析
1、时间复杂度
最坏的情况:时间复杂度为O(n²);
最佳的情况:时间复杂度为O(n²);
平均来讲,时间复杂度为O(n²)。
2、空间复杂度
空间复杂度为常量O(1)。

时间: 2024-10-29 03:48:17

插入排序之算法的相关文章

直接插入排序 快速排序算法 直接选择排序

以下三个验证性实验都做. (1)直接插入排序算法验证. (2)快速排序算法验证. (3)直接选择排序算法验证. #include<iostream> #include<cstdlib> using namespace std; class dishizhang { public: int a[10]; int b[10]; dishizhang() { int tem; for(int i = 0 ; i < 10 ; i ++) { while(1) { int flag

插入排序的算法描述和分析

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法. 它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上, 通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中, 需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间. 时间复杂度:最佳为o(n):因为如果是已经排序好的序列话,它每次只需和前面已排序好的序列比较一次,总共比较n次,也是可以通过flag实现的,然后最差时

插入排序之算法研究

插入排序:有n个数,第i个数前面都是有序的话,那么i插入到排好的系列中就非常简单,和前面的数一一比较就ok了,对于一个序列,那么从第二个数开始和前面数比较,排好前面2个数之后来把第三个数插入到前面2个数中就非常简单了,第四个数亦是如此,以此类推..................... #include<iostream> #include<vector> using namespace std; //void insert_sort(vector<int> &

《直接插入排序》算法设计之三

直接插入排序 每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的序列中,知道全部记录插入完成. 排序过程 1.每次插入的数值都要与自己前面的做比较 A.如果大于前面的数,则停止.因为每次都是排好的序列 B.如果小于前面的数,接着向前比较,指导找到自己的位置,插入即可 如右图所示 当插入2时,需要与前面做比较,直到找到自己合适的位置即可 当插入1时,用现在插入的数值依次与前面做比较,直到找到合适的位置即可 代码分析 通过以上的分析,因此我们可以采取以下思路来处理直接插入排序 方法一 找位

算法 排序lowB三人组 冒泡排序 选择排序 插入排序

参考博客:基于python的七种经典排序算法   [经典排序算法][集锦]     经典排序算法及python实现 首先明确,算法的实质 是 列表排序.具体就是操作的列表,将无序列表变成有序列表! 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性: 经过某种排序后,如果两个记录序号同等,且两者在原无序记录中的先后秩序依然保持不变,则称所使用的排序方法是稳定的,反之是不稳定

插入排序算法---插入排序与希尔排序

本文主要说明插入排序.shell排序两种排序方法.  一.插入排序  算法思想:  假定这个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止.这具算法在排完前k个数之后,可以保证a[1…k]是局部有序的,保证了插入过程的正确性. 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下: ⒈ 从第一个元素开始,该元素可以认为已经被排序 ⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描 ⒊ 如果

矿Java开发学习之旅------&amp;gt;Java排序算法经典的二分法插入排序

一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为採用折半比較,就可以得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比較,就是在插入A[i]时,取A[i-1/2]的关键码值与A[i]的关键码值进行比較,假设A[i]的关键码值小于A[i-1/2]的关键码值.则说明A[i]仅仅能插入A[0]到A[i-1/2]之间.故能够在A[0]到A[i-1/2-1]之间继续使用折半比較:否则仅仅能插入A[i-1/2]到A[i-1]之间

#排序算法#【2】直接插入排序、希尔排序

直接插入排序法 插入排序的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后移动,为最新元素提供插入空间. 核心代码: //直接插入排序法 void InsertSort(int a[],int n){ int i,j,k,t; for(i = 1 ; i<n;i++){ k = a[i]; /* 第一次比较粗糙的写法 j = i-1; while(

二分法插入排序算法的尝试

这是一个<算法导论>上的练习,可将插入排序的总体运行时间降至Θ(nlgn),我们先看看插入排序的算法代码: #include <stdio.h> int main(void) { int arr[] = {6,3,1,5,4,2}; int i, j; int temp; for(i = 1; i < sizeof(arr)/sizeof(int); i++) //运行时间Θ(n) { temp = arr[i]; j = i - 1; while(j >= 0 &am