1. 程式人生 > >排序演算法總結之插入排序

排序演算法總結之插入排序

一,插入排序介紹

 插入排序是基於比較的排序。所謂的基於比較,就是通過比較陣列中的元素,看誰大誰小,根據結果來調整元素的位置。

因此,對於這類排序,就有兩種基本的操作:①比較操作; ②交換操作

其中,對於交換操作,可以優化成移動操作,即不直接進行兩個元素的交換,還是用一個樞軸元素(tmp)將當前元素先儲存起來,然後執行移動操作,待確定了最終位置後,再將當前元素放入合適的位置。(下面的插入排序就用到了這個技巧)--因為,交換操作需要三次賦值,而移動操作只需要一次賦值

有些排序演算法,比較次數比較多,而移動次數比較少,而有些則相反。比如,歸併排序和快速排序,前者移動次數比較多,而後者比較次數比較多。

這裡主要介紹插入排序

二,插入排序演算法分析

插入排序演算法有種遞迴的思想在裡面,它由N-1趟排序組成。初始時,只考慮陣列下標0處的元素,只有一個元素,顯然是有序的。

然後第一趟 對下標 1 處的元素進行排序,保證陣列[0,1]上的元素有序;

第二趟 對下標 2 處的元素進行排序,保證陣列[0,2]上的元素有序;

.....

.....

第N-1趟對下標 N-1 處的元素進行排序,保證陣列[0,N-1]上的元素有序,也就是整個陣列有序了。

它的遞迴思想就體現在:當對位置 i 處的元素進行排序時,[0,i-1]上的元素一定是已經有序的了。

三,插入排序演算法實現

 1
public class InsertSort{ 2 3 public static <T extends Comparable<? super T>> void insertSort(T[] a){ 4 for(int p = 1; p < a.length; p++) 5 { 6 T tmp = a[p];//儲存當前位置p的元素,其中[0,p-1]已經有序 7 int j; 8 for(j = p; j > 0 && tmp.compareTo(a[j-1]) < 0; j--)
9 { 10 a[j] = a[j-1];//後移一位 11 } 12 a[j] = tmp;//插入到合適的位置 13 } 14 } 15 16 //for test purpose 17 public static void main(String[] args) { 18 Integer[] arr = {34,8,64,51,32,21}; 19 insertSort(arr); 20 for (Integer i : arr) { 21 System.out.print(i + " "); 22 } 23 } 24 }

四,複雜度分析

 ①插入排序的時間複雜度 就是判斷比較次數有多少,而比較次數與 待排陣列的初始順序有關,當待排陣列有序時,沒有移動操作(第8行for不成立),此時複雜度為O(N),當待排陣列是逆序時,比較次數達到最大--對於下標 i 處的元素,需要比較 i-1 次。總的比較次數:1+2+...+N-1 ,故時間複雜度為O(N^2)

①可以看出,演算法中只用到了一個臨時變數(第6行),故空間複雜度為O(1)

其實,插入排序的比較次數與陣列的逆序數相關,因為插入排序在將某個元素插入到合適位置時(程式碼第12行),其實就是消除這個元素的逆序數。

由定理:N個互異數的陣列的平均逆序數是 N(N-1)/4,可知:基於相鄰元素之間的比較和交換的演算法的時間複雜度的一個下界為O(N^2)

比較氣泡排序啊。。。。它採用的思路是:相鄰兩個元素比較,將小的放在前頭。故氣泡排序的時間複雜度為O(N^2)。。。

基於上面這個定理,另外一個排序演算法:希爾排序,採用了增量序列。因此,它可能獲得一個更好的時間複雜度。

比如,當希爾排序使用Hibbard增量序列時,它的最壞執行時間為O(N3/2)

五,參考資料

《資料結構與演算法分析》MAW著

相關推薦

排序演算法總結插入排序

一,插入排序介紹  插入排序是基於比較的排序。所謂的基於比較,就是通過比較陣列中的元素,看誰大誰小,根據結果來調整元素的位置。 因此,對於這類排序,就有兩種基本的操作:①比較操作; ②交換操作 其中,對於交換操作,可以優化成移動操作,即不直接進行兩個元素的交換,還是用一個樞軸元素(tmp)將當前元素先儲

排序演算法總結排序 Bucket Sort

private void bucketsort(double[] A) { int n = A.length; ArrayList<Double>[] list = new ArrayList[n]; for(int i=0;i<n;i++) { int tem

七大內部排序演算法總結插入排序、希爾排序、氣泡排序、簡單選擇排序、快速排序、歸併排序、堆排序

寫在前面:         排序是計算機程式設計中的一種重要操作,它的功能是將一個數據元素的任意序列,重新排列成一個按關鍵字有序的序列。因此排序掌握各種排序演算法非常重要。對下面介紹的各個排序,我們假定所有排序的關鍵字都是整數、對傳入函式的引數預設是已經檢查好了的。只

排序演算法總結排序

一,堆排序介紹 堆是一個優先順序佇列,對於大頂堆而言,堆頂元素的權值最大。將 待排序的陣列 建堆,然後不斷地刪除堆頂元素,就實現了排序。關於堆,參考:資料結構--堆的實現之深入分析 下面的堆排序演算法將陣列中的元素從小到大排序,用大頂堆來實現。 二,堆排序演算法分析  現給定了一維陣列,需要將陣列

排序演算法總結歸併排序

一,歸併排序介紹 歸併排序是一個典型的基於分治的遞迴演算法。它不斷地將原陣列分成大小相等的兩個子陣列(可能相差1),最終當劃分的子陣列大小為1時(下面程式碼第17行left小於right不成立時) ,將劃分的有序子陣列合併成一個更大的有序陣列。為什麼是有序子陣列??? 歸併排序的遞迴公式:T(N) = 2

排序演算法總結快速排序

一,快速排序介紹 快速排序與歸併排序一樣,也是基於分治的遞迴演算法,體現在:在每一趟快速排序中,需要選出樞軸元素,然後將比樞軸元素大的陣列元素放在樞軸元素的右邊,比樞軸元素小的陣列元素都放在樞軸元素的左邊。然後,再對分別對 樞軸元素左邊 和 樞軸元素右邊的元素進行快速排序。 二,快速排序演算法分析

排序演算法總結氣泡排序

氣泡排序(Bubble Sort,臺灣譯為:泡沫排序或氣泡排序)是一種簡單的排序演算法。它的基本思想就是兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地

排序演算法總結折半插入排序

基本思想折半插入排序是對直接插入排序的簡單改進,對於直接插入排序而言,當第i-1趟需要將第i個元素插入前面的0~i-1個元素序列中時,總是需要從i-1個元素開始,逐個比較每個元素,直到找到它的位置。這顯然沒有利用前面0~i-1個元素已經有序這個特點,而折半插入排序則改進了這一

資料結構與演算法C++插入排序(續)

上一篇資料結構與演算法C++之插入排序中使用C++實現了插入排序演算法,但是使用了交換操作(swap),一次swap操作包括三次移位操作,造成執行時間比較長,本篇部落格對其改進。 (1)首先,考慮第一個元素8,此時只有一個元素,是排好序的 (2)然後考慮第二個元素6 (3)將元素6拷

資料結構與演算法C++插入排序

本篇實現的是插入排序,其演算法複雜度是O(n2),插入排序的原理來自部落格: 插入排序原理很簡單,將一組資料分成兩組,分別將其稱為有序組與待插入組。左邊為有序組,右邊為待插入組,每次從待插入組中取出一個元素,與有序組的元素進行比較,並找到合適的位置,將該元素插到有序組當中。就這樣,每次插

基礎算法系列排序演算法-3. 直接插入排序 並用其解決HDU 1106 排序

      我們之前已經學習了氣泡排序和二分查詢兩種基本演算法,本篇文章我們將一起學習下一個基礎演算法——直接插入排序演算法。  直接插入排序      直接插入排序,從這個名字來看,是不是讓你想到了什麼場景?!對了,就是打撲克牌的場景,我們每摸一張牌,是不是按照一定的次

基礎算法系列排序演算法-6.折半插入排序 並用解決hdu 1412問題

       我們之前已經瞭解了5種基礎演算法,是否自己找了一些題練練手呢~話不多說,讓我們進入第6中基礎演算法的學習吧。本篇我們將學習又一種排序演算法——折半插入排序演算法,跟上篇我們所學習的快速排序有點像,都是建立在我們之前學習的演算法的基礎上改進而來的。從這個演算法的名

演算法導論插入排序

排序問題 輸入: n個數的一個序列< A1,A2 , … , An >。 輸出: 序列的一個排列< A1’ , A2’ , … , An’ >, 滿足A1’ <= A2’ <= … <= An’ , 或者 A1’&

排序算法插入排序

oid code wap for pre spa 每次 [] 位置 思路:   每次叠代都和前面的元素進行比較,如果小於前面的元素則把當前元素和其前面的元素進行交換,然後接著再比較和前面元素的大小,若還是小於前面的元素則繼續進行交換。如果大於前面的元素則終止當前的叠代。和選

八大排序算法插入排序

代碼實現 == 記錄 分析 tro return dom span col 算法思想:每一趟將一個待排序的記錄,按照其關鍵字的大小插入到有序隊列的合適位置裏,知道全部插入完成。 設計步驟:   假設有一組無序序列 R0, R1, ... , RN-1。   (1) 我們先

Java排序算法插入排序

.so main out [] ast public struct ++ clas package com.example.demo.dataStructure.sort; // 直接插入排序 public class InsertSort { public s

排序演算法大雜燴排序

排序演算法大雜燴主幹文章傳送門 堆排序 #include <iostream> #include <vector> /* 非降序排序 時間複雜度:o(nlgn) 空間複雜度:o(nlgn) 建堆:o(n) 維護堆:o(lgn) 不穩定 */ using n

排序演算法大雜燴歸併排序

排序演算法大雜燴主幹文章傳送門 歸併排序 #include <iostream> #include <vector> using namespace std; //典型的分治策略,拆分,解決,合併 void Merge(vector<int>

排序演算法大雜燴快速排序

排序演算法大雜燴主幹文章傳送門 快速排序 接著主文章結構繼續分析快速排序 快速排序實現主流上分為兩種,第一種為快排的開山鼻祖 C

排序演算法2】插入排序

插入排序的中心思想就是將一個元素插入到已經排好序的陣列當中。 陣列a[n] 初始時,a[0]自成一格有序區,無序區為a[1…n-1] 令i = 1 將a[i]併入當前有序區a[0…i-1]中形成有序區間 i++並重復第二步直到 i == n -1 #include <stdio