簡單排序演算法的時間下界

2021-09-02 03:57:19 字數 1640 閱讀 8323

插入排序

插入排序是最簡單的排序演算法之一,對於n個元素的序列,需要進行n-1次的插入來完成排序。插入排序的演算法:

(1)對於位置p,0到p-1位置上的元素已經是有序的,p從1開始;

(2)將p指向的元素放到[0,p]正確的位置,這樣0到p位置上的元素也是有序的。

插入排序確實很簡單,不需要過多的介紹,直接用乙個示例來演示其過程,待排序列:2 4 6 1 3 5 總共有6個元素,所以需要5趟排序,p從1開始

(1)2是乙個有序序列

(2)p=1,將4插入到正確位置,排序後:2 4

(3)p=2,將6插入到正確位置,排序後:2 4 6

(4)p=3,將1插入到正確位置,排序後:1 2 4 6

(5)p=4,將3插入到正確位置,排序後:1 2 3 4 6

(6)p=5,將5插入到正確位置,排序後:1 2 3 4 5 6

插入排序**:

void insertsort(int *a,int n) 

}

上面的**實現是比較好的,它移動實現了元素移動,卻沒有明顯的使用交換,而是使用x儲存待插入元素,不斷將x之前的元素往右移動,直到空出適合x插入的位置。

時間複雜度分析

對於p每乙個值,**中第6行的內層for迴圈最多執行p+1次比較,對所有的p求和:

t(n) = 2 + 3 + 4 + .... + n = o(n^2) = o(n^2)

如果輸入是有序的,那麼內層for迴圈就不會執行,因此時間複雜度是o(n),這是最好的情形。平均時間複雜度是:o(n^2) = o(n^2)

簡單排序的時間下界

陣列的乙個逆序:陣列中i < j,但a[i] > a[j]的序偶(a[i],a[j])。

在上面的序列中存在(2,1),(4,1),(4,3),(6,1),(6,3),(6,5)這6個逆序。想一下插入排序的過程,如果待插入元素與前面的元素存在逆序,那麼就需要交換資料,每次都是和相鄰的元素交換,交換一次只能消除乙個逆序。也就是說陣列中的逆序個數就是排序時的交換次數。 插入排序時,除了交換外還有其他o(n) 項工作,設i為原陣列中的逆序數,因此插入排序的時間複雜度是o(i + n)。如果能求出i的平均值,也就求出了插入排序的平均時間複雜度。

定理:n個互異的陣列的平均逆序數是n(n - 1) / 4。

證明:對於任意序列l,其反序是~l,對於l中的任意兩個數(x,y),且y > x。如果x在y的前面,那麼對於~l而言,x就在y的後面,(x,y)就是~l的逆序:

l:..... x ...... y ......

~l:....... y ....... x .......

反之,如果x在y的後面,(x,y)就是l的逆序。總之,對於任意(x,y),它要麼是l的逆序,要麼是~l的逆序。這樣l + ~l的逆序總和是:c(n,2) = n(n - 1) / 2。l的平均逆序就應該是總量的一半:n(n-1) / 4。

序列的平均逆序數是二次的,交換相鄰元素只能消除乙個逆序。因此,凡是通過只交換相鄰元素的排序演算法的平均時間是二次的,這是這類演算法乙個很強的下界。因此我們又得到乙個定理:通過交換相鄰元素進行排序的任何演算法平均需要ω(n^2)。

這個下界告訴我們,為了以亞二次時間執行,必須要對相距較遠的元素進行交換,這樣的一次交換可能會消除多個逆序。

簡單排序演算法

package com.shine.sort 排序演算法 說明 排序演算法分為三種 插入排序 交換排序 選擇排序 1.插入排序 直接插入排序 折半插入排序 希爾排序 2.交換排序 氣泡排序 快速排序 3.選擇排序 直接選擇排序 堆排序 public class mysort 希爾排序 描述 1.將乙...

簡單排序演算法

演算法思想 將初始序列 a 0 a n 1 作為待排序序列,第一趟在待排序序列 a 0 a n 1 中找最小值元素,與該序列中第乙個元素a 0 交換,這樣的子串行 a 0 有序,下一趟排序在待排序子串行 a 1 a n 1 中進行。第i趟排序在待排序子串行 a i 1 a n 1 中,找最小值元素,...

簡單排序演算法

第乙個 氣泡排序 簡單來說,就是不停的與旁邊的比較,然後交換,總之運算的交換次數挺多的,後面再來比較幾種排序方法 void bubblesorthead int pdata,int count 這是一種實現形式,還有另一種 void bubblesorttail int pdata,int coun...