資料結構和演算法學習第六節 排序演算法 一 基本概念

2021-10-17 04:55:05 字數 4138 閱讀 5455

排序演算法:是將一組資料,按照指定的順序進行排列的過程。

排序的分類:

1、內部排序:將需要處理的所有資料載入到記憶體儲存器中排序

2、外部排序:資料量過大,無法全部載入到記憶體中,需要借助外部儲存進行排序。

常見的排序演算法分類如下所示,外部排序先略過。

衡量乙個程式(演算法)執行時間的兩種方法

1、事後統計法

這種方法可行,但是有兩個問題,1)如果想要對設計的演算法進行執行效能評測,需要實際執行程式。2) 運算的所得的時間的統計量依賴於計算機的硬體、軟體等環境因素,這種方式需要在同等條件、同等狀態下執行,才能比較演算法的速度。

2、事前估算法:通過分析某個演算法的時間複雜度來判斷哪個演算法更好。

時間頻度

乙個演算法花費的時間與演算法中語句的執行次數成正比,哪個演算法語句執行次數越多,它消耗時間越多。乙個演算法中的語句執行次數稱為語句頻度或者時間頻度,記為t(n)。

時間頻度簡要說明

@test

// 計算 1 + 2 + 3 …… + 99 + 100

public

void

method1()

system.out.

println

(total);}

@test

// 計算 1 + 2 + 3 …… + 99 + 100

public

void

method2()

演算法的時間複雜度可以忽略常數項。2n+5 隨著n逐漸增加,執行曲線無限接近

3n+10 隨著n逐漸增加,執行曲線無限接近

同理:可以忽略低次項 、忽略係數。比如 t(n) = 2n2 與 t(n) = 2n2 +3n,可以忽略低次項。比如 t(n) = 3n2 與 t(n) = 2n2 當n越來越大,係數也可以忽略。

時間複雜度簡要說明

1、一般情況下,演算法中的基本操作語句的重複執行次數是問題規模n的某個函式,使用t(n)表示。若有某個輔助函式f(n),使得當n趨近於無窮大時,t(n)/f(n)的極限值為不等於0的常數,則稱f(n)是t(n)的同數量級函式,記作t(n)= o(f(n)) ,稱o(f(n))為演算法的漸進時間複雜度,簡稱時間複雜度。

2、t(n)不同,但是時間複雜度可能相同,比如 t(n) = n2+7n+6與t(n) = 2n2+3n+1,他們的t(n)不同,但是時間複雜度相同,都是o(n2)

3、計算時間複雜的方法

3.1、使用常數1代替執行時間中的所有加法常數。

3.2、修改後得到執行次數函式中,只保留最高端項。

3.3、去除高階項的係數。

常見的時間複雜度

1、常數階o(1)

2、對數階o(log⁡2

n\log_2 n

log2​n

)3、線性階o(n)

4、常數對數階o(nlog⁡2

n\log_2 n

log2​n

)5、平方階o(n2)

6、立方階o(n3)

7、k次方階o(nk)

8、指數階o(2n)

常見的演算法時間複雜度,由小到大依次為:o(1) < o(log⁡2

n\log_2 n

log2​n

) < o(n) < o(nlog⁡2

n\log_2 n

log2​n

) < o(n2) < o(n3) < o(nk) < o(2n),隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低,應該盡可能避免使用指數階的演算法。簡要示意圖如下:

常見的時間複雜度舉例說明:

常數階o(1)

// 常數階 無論**執行了多少行,只要沒有迴圈等複雜結構,那麼這個**的時間複雜度都是o(1)

public

voidm1(

)

2、對數階o(log⁡2

n\log_2 n

log2​n

)

// 對數階說明

public

voidm2(

int n)

}

對數階簡要說明:

在while迴圈中,每次都將i乘以2,i的值與n越來越接近。假設迴圈k次,i就大於n了,此時這個迴圈就退出了,也就是說2k >= n,那麼 k = log⁡2

n\log_2 n

log2​n

,當迴圈log⁡2

n\log_2 n

log2​n

次以後,**就結束向下執行。所以這段**的時間複雜度為o(log⁡2

n\log_2 n

log2​n

)。假設,**修改為i = i * 3;此時的時間複雜度為o(log⁡3

n\log_3 n

log3​n

)。如果 n = ax (a > 0,a ≠

\neq

​= 1),即a的x次方等於n(a > 0,a ≠

\neq

​= 1),那麼數x就是以a為底n的對數,記作 x = log⁡a

n\log_a n

loga​n

,a是對數的底數,n是真數,x是「以a為底n的對數」。

線性階

// 線性階說明

public

voidm3(

int n)

}

線性對數階

// 線性對數階說明

// 線性對數階其實就是將對數階**迴圈了n遍

public

voidm4(

int m,

int n)

}}

平方階

// 平方階

public

voidm5(

int n)

}}

平均時間複雜度和最壞時間複雜度1、平均時間複雜度是指所有可能的輸入例項以等概率出現的情況下,該演算法的執行時間。

2、最壞情況下的時間複雜度是最壞時間複雜度,一般討論的時間複雜度是最壞情況下的時間複雜度,這樣做的原因是:最壞情況下的時間複雜度,是演算法在任何例項上執行時間的界限,這就保證了演算法的執行時間不會比最壞情況更長。

3、排序演算法的時間複雜度如下圖所示。

排序演算法

平均時間

最壞情況

穩定度額外空間

備註氣泡排序

o(n2)

o(n2)

穩定o(1)

n小時較好

交換排序

o(n2)

o(n2)

不穩定o(1)

n小時較好

選擇排序

o(n2)

o(n2)

不穩定o(1)

n小時較好

插入排序

o(n2)

o(n2)

穩定o(1)

大部分已經排序好時較好

基數排序

o(log⁡r

b\log_r b

logr​b

)o(log⁡r

b\log_r b

logr​b

)穩定o(1)

b是真數,r是基數

希爾排序

o(nlogn)

o(ns) 1不穩定

o(1)

s是所選分組

快速排序

o(nlogn)

o(n2)

不穩定ologn

n大時較好

歸併排序

o(nlogn)

o(nlogn)

穩定o(n)

n大時較好

堆排序o(nlogn)

o(nlogn)

不穩定o(1)

n大時較好

學習Python的第六節課 函式和變數作用域

函式的本質就是一段有特定功能 可以重複使用的 1 內建函式python自帶的可直接呼叫的函式。比如 int input print 2 庫函式 庫函式匯入 import 模組名 from 模組名 import 執行過程 先判斷表示式的值,當其值為true或其他非0值,執行語句塊1,否則執行語句塊2。...

資料結構和演算法學習六,之非遞迴排序

在上面一篇部落格當中,我們發現普通查詢和排序查詢的效能差別很大。作為乙個100萬的資料,如果使用普通的查詢方法,那麼每乙個資料查詢平均下來就要幾十萬次,那麼二分法的查詢呢,20多次就可以搞定。這中間的差別是非常明顯的。既然排序有這麼好的效果,那麼這篇部落格中,我們就對排序算做乙個總結。按照我個人的理...

資料結構和演算法學習六,之非遞迴排序

在上面一篇部落格當中,我們發現普通查詢和排序查詢的效能差別很大。作為乙個100萬的資料,如果使用普通的查詢方法,那麼每乙個資料查詢平均下來就要幾十萬次,那麼二分法的查詢呢,20多次就可以搞定。這中間的差別是非常明顯的。既然排序有這麼好的效果,那麼這篇部落格中,我們就對排序算做乙個總結。按照我個人的理...