1. 程式人生 > >插入排序,希爾排序原理,程式碼及複雜度分析

插入排序,希爾排序原理,程式碼及複雜度分析

插入排序演算法

演算法原理:
* 插入排序原理很簡單,講一組資料分成兩組,
* 我分別將其稱為有序組與待插入組。
* 每次從待插入組中取出一個元素,與有序組的元素進行比較,並找到合適的位置,
* 將該元素插到有序組當中。就這樣,每次插入一個元素,有序組增加,待插入組減少。
* 直到待插入組元素個數為0。
* 當然,插入過程中涉及到了元素的移動。
*/

例如:45 80 48 40 22 78 
第一輪:45 80 48 40 22 78 ---> 45 80 48 40 22 78 i=1

第二輪:45 80 48 40 22 78 ---> 45 48 80 40 22 78 i=2

第三輪:45 48 80 40 22 78 ---> 40 45 48 80 22 78 i=3
第四輪:40 45 48 80 22 78 ---> 22 40 45 48 80 78 i=4
第五輪:22 40 45 48 80 78 ---> 22 40 45 48 78 80 i=5

圖解:(圖片來自網路  侵權刪除)



實現程式碼如下:

public void InsertSort(int arr[]){
		int i,j,temp;
		for(i=1;i<arr.length;i++){//從第二個元素開始,第一個預設為有序的
			temp=arr[i];//準備排序的那個元素
			j=i-1;//排好序的數列的最後一個元素
			while(j>=0&&temp<arr[j]){//j>=0表示插入的邊界,
				arr[j+1]=arr[j];//排序數列後移一個序列
				j--;
			}
			arr[j+1]=temp;
		}
		
	}

 時間複雜度:

最好情況(原本就是有序的)
比較次數:Cmin=n-1
移動次數:Mmin=0

最差情況(逆序)

比較次數:Cmax=2+3+4+……+n=(n+2)n/2
移動次數:Mmax=1+2+3+……+n-1=n*n/2

故時間複雜度為o(n^2)

希爾排序

演算法原理:

先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d2<d1重複上述的分組和排序,直至所取的增量 =1(  <  …<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。

圖解(圖片來自網路,侵權刪除)

實現程式碼:

public  void  shellSort(int arr[]){
		int i,j,temp,len;
		len=arr.length;
		for(int step=len/2;step>0;step=step/2){//最外外層迴圈,根據步長分組
			//   for (step = len / 2; step > 0; step /= 2)  
			for(i=0;i<step;i++){//用直接插入法對每一組進行排序
				for(j=i+step;j<len;j=j+step){
					
					if(arr[j]<arr[j-step]){
						temp=arr[j];
						int k=j-step;//已經排序的最後一個元素的下標
						while(k>=0&&arr[k]>temp){
							arr[k+step]=arr[k];//排序序列右移步長個序列
							k=k-step;//找前一個元素
						}
						arr[k+step]=temp;//找到合適的位置 則直接插入
					}
				}
			}
		}
	}

 希爾排序的時間複雜度:

平均時間複雜度:希爾排序的時間複雜度和其增量序列有關係,這涉及到數學上尚未解決的難題;不過在某些序列中複雜度可以為O(n1.3);

排序方法時間複雜度(平均)時間複雜度(最壞)時間複雜度(最好)空間複雜度穩定性複雜性
直接插入排序
n2
O(n2)

O(n2)
O(n)
O(1)
穩定 簡單
希爾排序

O(nlog2n)

n2
O(n2)
O(n) O(1) 不穩定 較複雜

總結:

爾排序是基於插入排序的以下兩點性質而提出改進方法的:
  1. 插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率。
  2. 但插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位。

相關推薦

插入排序排序原理程式碼複雜分析

插入排序演算法 演算法原理: * 插入排序原理很簡單,講一組資料分成兩組, * 我分別將其稱為有序組與待插入組。 * 每次從待插入組中取出一個元素,與有序組的元素進行比較,並找到合適的位置, * 將該元素插到有序組當中。就這樣,每次插入一個元素,有序組增加,待插入組減少。 * 直到待插入組元素個數

經典排序演算法氣泡排序選擇排序直接插入排序排序快速排序歸併排序二分查詢。原理python實現。

1.氣泡排序 氣泡排序 1.比較相鄰的元素,如果第一個比第二個大(升序),就交換他們兩個 2.對每一對相鄰的元素做同樣的工作,從開始到結尾的最後一對 這步做完後,最後的元素會是最大的數 3.針對所有的元素重複以上的步驟,除了最

排序上篇(選擇排序氣泡排序插入排序排序

1.選擇排序 (1)原理:  在要排序的一組數中,用第一個數與後面的數依次進行判斷,若大於後面的則進行交換;然後依次再用第二個數與後面的數進行交換,如此迴圈到倒數第二個數和最後一個數比較為止。 (2)圖解: 內層第一次迴圈如下:   外層控制迴圈次數:

插入排序排序

# -*- coding: utf-8 -*- """ Created on Sun Nov 18 13:28:49 2018 """ #插入排序難點 插入排序(英語:Insertion Sort)是一種簡單直觀的排序演算法。 它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前

順序表儲存實現氣泡排序選擇排序插入排序排序基數排序

#include<iostream> using namespace std; const int MAXSIZE = 100; typedef int ElemType; struct Data { ElemType key; // int shu

3. 排序通常有多種演算法如氣泡排序插入排序、選擇排序排序、歸併排序、快速排序請選擇任意2種用java實現 [分值:20] 您的回答:(空) (簡答題需要人工評分)

3. 排序通常有多種演算法,如氣泡排序、插入排序、選擇排序、希爾排序、歸併排序、快速排序,請選擇任意2種用java實現  [分值:20] 您的回答:(空)  (簡答題需要人工評分) package com.interview; /** * 各種排序演算法 */

各種排序演算法的場景以及c++實現(插入排序排序氣泡排序快速排序選擇排序歸併排序

對現有工作並不是很滿意,所以決定找下一個坑。由工作中遇到排序場景並不多,大都是用氣泡排序,太low,面試又經常問到一些排序演算法方面的東西。剛好讓小學妹郵的資料結構也到了。就把各種排序演算法重新總結一下,以作留存。 排序分為內部排序和外部排序,內部排序是在記憶體中排序。外

優化的直接插入排序(二分查詢插入排序排序

   本博文向大家介紹了插入排序的三種實現:直接插入排序,二分查詢插入排序,希爾排序。詳細分析的其實現過程、時間複雜度和空間複雜度、穩定性以及優化改進策略。最後簡單的做了下效能測試。 直接插入排序 (一)概念及實現 直接插入排序的原理:先將原序列分為有序區和無序區,然後再經過比較和後移操作將無序

插入排序排序選擇排序快速排序氣泡排序歸併排序

插入排序 1、介紹:        簡單插入排序演算法原理:從整個待排序列中選出一個元素插入到已經有序的子序列中去,得到一個有序的、元素加一的子序列,直到整個序列的待插入元素為0,則整個序列全部有序。   在實際的演算法中

排序演算法(一)氣泡排序簡單選擇排序直接插入排序排序

氣泡排序,簡單選擇排序,直接插入排序是三種複雜度為O(n2)的演算法,希爾排序在特殊增量序列的時候可以獲得複雜度為O(n3/2) 氣泡排序 1、最簡單的排序實現 這裡把每個數和這個數之後的每個數比較,大於就交換位置。 缺點:多出了很多次沒有用的交

Python八大演算法的實現插入排序排序、氣泡排序、快速排序、直接選擇排序、堆排序、歸併排序、基數排序

1、插入排序 描述 插入排序的基本操作就是將一個數據插入到已經排好序的有序資料中,從而得到一個新的、個數加一的有序資料,演算法適用於少量資料的排序,時間複雜度為O(n^2)。是穩定的排序方法。插入演算法把要排序的陣列分成兩部分:第一部分包含了這個陣列的所有元素,但將最後一

資料結構之排序演算法(五)-直接插入排序排序直接選擇排序

直接插入排序:時間複雜度:O(n^2) 基本演算法思路是:把後面待排序的記錄按其關鍵字的大小逐個插入到一個已經排好序的有序序列中,直到所有記錄插完為止,得到一個新的有序序列。(無序插入前面有序) 演算

C語言實現直接插入排序氣泡排序選擇排序排序快排

     直接插入演算法,每次將未排序的第一個元素插入到前半部分以及排好序的元素中。關鍵是要在已排好的部分進行移位操作。//直接插入排序演算法 void InsertSort(int a[],int n) { for (int i = 1; i < n; i++) {

氣泡排序選擇排序插入排序排序排序歸併排序快速排序實現

前言:排序的定義 排序是計算機內經常進行的一種操作,其目的是將一組“無序”的記錄序列調整為“有序”的記錄序列。分內部排序和外部排序,若整個排序過程不需要訪問外存便能完成,則稱此類排序問題為內部排序。反之,若參加排序的記錄數量很大,整個序列的排序過程不可能在記憶

直接插入排序折半插入排序排序

直接插入排序 時間複雜度: 最好 O(n)  最壞 O(n^2) 平均(n^2) 空間複雜度:O(1); void InsertSort(int *a){//直接插入排序 int j, temp; for(int i = 2; i <= a[

通俗理解插入排序(直接插入排序折半插入排序排序

直接插入排序 直接插入排序就是將待排序的值,逐一按元素的大小插入前面的有序序列 例如對-23,45,2,-45,9,5,3,65,-24進行直接插入排序,我們可以看成將45,2,-45,9,5,3,65,-24逐步插入-23的序列 package

排序演算法: 氣泡排序 快速排序排序,直接插入排序 直接選擇排序,歸併排序,堆排序

幾種排序演算法分析:   氣泡排序:   氣泡排序的方法排序速度比較慢。   思路:進行n-1排序,第一次排序先找出最小的數字,放在第一個位置,然後在剩餘的數字中再找出最小的數字,放在第二個位置上,依次類推,可以排出所有的數字。   當然也可以從大到小的排序。   例如

Java資料結構:排序演算法(氣泡排序選擇排序插入排序排序快速排序排序和合並排序

public class 氣泡排序 { public static void main(String[] args) { int a[] = { 1, 9, 6, 8, 5, 65, 65, 84, 1, 2, 5, 23, 7, 889 }; for (int i

基本排序(三):插入排序排序- 從後向前掃描比正操作元素大的逐步移位

1. 插入排序 插入排序(Insertion Sort)工作原理(維基百科) 通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置插入。插入排序實現上,通常採用in-place排序(即只需用到O(1)的額外空間的排序),因而在從後向

常用排序:氣泡排序選擇排序插入排序排序歸併排序快速排序

#include <stdio.h> #define MAX 10 typedef int  ElementType; typedef ElementType ARR[MAX]; void swap(ARR arr,int i,int j) {     E