算法之插入排序法

插入排序法(Insertion Sort)

一,概念

  • 自行總結:當前元素小於(大於)前一個元素,則當前元素就插入到前一個元素以前,直到排序完成
  • 區別:javascript

    • 插入排序:二層循環能夠提早結束循環
    • 選擇排序:二層循環要所有執行
  • 時間複雜度:O(n2)
  • 特色:若是待排序數組近乎有序,那能夠很快結束二層循環,時間複雜度趨於O(n)

二,圖示

更接近,插入排序改進方法的邏輯
在這裏插入圖片描述java

三,C++實現

main.cppios

#include <iostream>
#include <algorithm>
#include "SortTestHelper.h"
#include "SelectionSort.h"

using namespace std;

template<typename T>
void insertionSort(T arr[], int n){

    for( int i = 1 ; i < n ; i ++ ) {

        // 尋找元素arr[i]合適的插入位置(和以前元素進行比較)
        // 插入排序的二層循環能夠提早結束,但選擇排序的二層循環要完整執行找到最小值
        // 寫法1
        for( int j = i ; j > 0 ; j-- )
            if( arr[j] < arr[j-1] )
                swap( arr[j] , arr[j-1] );
            else
                break;

        // 寫法2
//        for( int j = i ; j > 0 && arr[j] < arr[j-1] ; j -- )
//            swap( arr[j] , arr[j-1] );

    }

    return;
}

int main() {

    int n = 10000;
    cout<<"Test for Random Array, size = "<<n<<", random range [0, "<<n<<"]"<<endl;
    int *arr1 = SortTestHelper::generateRandomArray(n,0,n);
    int *arr2 = SortTestHelper::copyIntArray(arr1, n);

    SortTestHelper::testSort("Insertion Sort", insertionSort,arr1,n);
    SortTestHelper::testSort("Selection Sort", selectionSort,arr2,n);

    delete[] arr1;
    delete[] arr2;

    cout<<endl;

    return 0;
}

SortTestHelper.hc++

int *copyIntArray(int a[], int n){

        int *arr = new int[n];
        copy(a, a+n, arr);
        return arr;
    }

四,js實現

// 插入排序
function insertionSort(arr, n){
    for(let i = 1; i < n; i++){
        // 尋找元素arr[i]合適的插入位置(和以前元素進行比較)
        // 插入排序的二層循環能夠提早結束,但選擇排序的二層循環要完整執行找到最小值
        for(let j = i; j > 0; j--){
            if(arr[j]< arr[j-1]){
                [arr[j], arr[j-1]] = [arr[j-1], arr[j]];
            }else{
                break;
            }
        }
    }
    return arr;
}

// 生成隨機數組
function getRandom(n){
    let arr = [];
    for (let i = 0; i < n; i++){
        arr[i] = Math.floor(Math.random() * n);
    }
    return arr;
}

insertionSort(getRandom(100),100);

五,排序時間比較

選擇排序比插入排序時間。插入排序雖然能提早結束循環,可是一直交換賦值。而選擇排序每次只有一次交換。數組

c++dom

int *arr1 = SortTestHelper::generateRandomArray(n,0,n);
int *arr2 = SortTestHelper::copyIntArray(arr1, n);

SortTestHelper::testSort("Insertion Sort", insertionSort,arr1,n);
SortTestHelper::testSort("Selection Sort", selectionSort,arr2,n);

jsspa

let arr1 = getRandom(100);
// copy數組
let arr2 = [...arr1];

console.time("sort");
selectionSort(arr1,100);
console.timeEnd("sort");

console.time("sort");
insertionSort(arr2,100);
console.timeEnd("sort");

六,插入排序改進

問題:對於插入排序屢次交換賦值的缺點,能不能改爲一次賦值?code

自行總結:把待插入的元素拿出,向前比較,比它大的元素後移,直到找到本身的位置,一次插入。blog

c++排序

void insertionSort(T arr[], int n){

    for( int i = 1 ; i < n ; i ++ ) {
        
        // 寫法3
        T e = arr[i];
        int j; // j保存元素e應該插入的位置
        for (j = i; j > 0 && arr[j-1] > e; j--)
            arr[j] = arr[j-1];
        arr[j] = e;
    }

    return;
}

js

// 插入排序
function insertionSort(arr, n){
    for(let i = 1; i < n; i++){
        let e = arr[i];// 把待插入的元素拿出
        let j = 0; // j保存元素e應該插入的位置
        for(j = i; j > 0; j--){
            if(e < arr[j-1]){ // 元素e向前比較
                arr[j] = arr[j-1];// 大於e的元素後移
            }else{
                break;
            }
        }
        // 當循環終止時(e > arr[j-1]),e找到本身位置爲j
        arr[j] = e;
    }
    return arr;
}
相關文章
相關標籤/搜索