演算法與資料結構 五 基本排序演算法

2022-06-24 19:03:09 字數 2657 閱讀 9560

前面幾篇基本上把基本的資料結構都回顧完了,現在開始回顧那些常見的排序演算法。

排序是將一組無序的資料根據某種規則重新排列成有序的這麼乙個過程,當時在大學需要我們手工自己實現的主要有三種:選擇排序、插入排序和氣泡排序。因為它比較簡單,所以這裡把他們放到一起作為最基本的排序演算法。

插入排序的思路是這樣的:首先假設 中第乙個元素是乙個有序序列,從k2 開始插入到前面有序序列的適當位置從而使之前的有序序列仍然保持有序

這麼說可能有點抽象,我們以乙個例項來說明:

假設現在有這麼一組待排元素: 3,6,1,2,8,4,7;

先假設第乙個元素3 是乙個有序序列,從後續序列中取出6這個元素插入到前面的有序序列,得到3, 6 這麼乙個有序序列,此時序列為:3, 6, 1, 2, 8, 4, 7

現在3, 6 是乙個有序序列,從之前的序列中取出1,插入到有序序列的合適位置,得到1, 3, 6 這麼乙個有序序列,此時序列為: 1, 3, 6, 2, 8, 4, 7

接著從待排元素中取出2,插入到適當位置,得到有序序列 1, 2, 3, 6;此時序列為 1, 2, 3, 6, 8, 4, 7

以此類推,直到所有元素都排列完成,下面是每次排序後生成的序列

3 6 1 2 8 4 7

1 3 6 2 8 4 7

1 2 3 6 8 4 7

1 2 3 6 8 4 7

1 2 3 4 6 8 7

1 2 3 4 6 7 8

1 2 3 4 6 7 8

那麼知道了這個演算法的思想,下面就是考慮該如何將其轉化為**,由計算機幫助我們實現這些事了。

首先這段**至少有一層迴圈來依次取出序列中的待排元素,由於假定第乙個元素已經是有序的,所以迴圈次數應該是n - 1次,而且從序列的第2個元素開始。

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

那麼如何確定元素的適當位置呢,我們人從肉眼上來看肯定是可以看出來的,計算機並不知道啊。由於之前的序列肯定是有序的,所以這裡我們只需要從前往後將有序序列中的數與待插入數比較,只要序列中的數大於待插入數,那麼將帶插入數插入到該數的前面就可以了。因為之前的序列是有序的,插入到該位置肯定能保證新插入數大於它之前的數但是小於它之後的數。這個時候我們可以寫出這樣一段偽**

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

}}

同時在插入的時候需要考慮騰挪後續的元素,為了方便騰挪元素,應該從有序列表的後方向前面進行比較,在比較的同時進行元素的騰挪,直到找到位置,這個時候的**應該替換為這樣

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

a[j + 1] = tmp;

}

從演算法上來看,插入排序是一種o(n^2)的演算法

選擇排序是最好理解的一種演算法,選擇排序的基本思路是每次從待排序列中選擇最大(或者最小)的乙個,放到已排好的序列的最前面,形成乙個新的有序序列,直到所有元素都完成排序

仍然是之前的乙個序列 3, 6, 1, 2, 8, 4, 7

首先找到最小的數1,排到最前面:1, 6, 3, 2, 8, 4, 7

再找到後續最小數2,排到1後面:1, 2, 3, 6, 8, 4, 7

接著找到後續最小數3,排到2後面:1, 2, 3, 6, 8, 4, 7

以此類推,得到每次排序後的序列:

1 6 3 2 8 4 7

1 2 3 6 8 4 7

1 2 3 6 8 4 7

1 2 3 4 8 6 7

1 2 3 4 6 8 7

1 2 3 4 6 7 8

1 2 3 4 6 7 8

從上面來看,每次確定了最小數之後只需要將對應位置的數與這個最小數交換就完成了排序,這也是與插入排序不同的地方,插入排序在處理元素的時候採用騰挪的方式,而選擇排序則直接採用交換,也就是說插入排序在處理未排序元素的時候並沒有改變他們的位置,而選擇排序則有可能修改他們的位置,因此我們說選擇排序是一種不穩定的排序,而插入排序是穩定的排序.

實現的演算法如下:

for (int i = 0; i < n - 1; i++)

} if (k != i)

}

選擇排序的時間複雜度仍然是 o(n^2)

氣泡排序是在c語言課上講到的一種排序方式,簡單來說就是將待排序列中的資料從頭開始兩兩比較,然後將大數交換到後面,這樣每次迴圈之後總是大數沉到最後面,進行多次這樣的迴圈,就能完成排序

還是從 3, 6, 1, 2, 8, 4, 7 序列的排序開始

首先3與6相比,6大,此時不用交換,接著,6與1比較,6大然後進行交換。接著6與2比較,再交換,6與8比較,不用交換,8與4比較需要交換,8與7比較需要交換,因此第一次冒泡的結果是3, 1, 2, 6, 4, 7, 8

依次類推得到每次結果如下:

3 1 2 6 4 7 8

1 2 3 4 6 7 8

1 2 3 4 6 7 8

1 2 3 4 6 7 8

1 2 3 4 6 7 8

1 2 3 4 6 7 8

1 2 3 4 6 7 8

實現的演算法如下:

for (int i = 0; i < nlength - 1; i++)

}}

氣泡排序也是乙個不穩定的排序演算法,它的時間複雜度也是o(n^2)

資料結構 基本排序演算法

直接插入排序 c 實現 簡單選擇排序 c 實現 氣泡排序 c 實現 基本排序演算法.cpp 定義控制台應用程式的入口點。include stdafx.h includeusing namespace std void directinsertsorting int data,int size 直接插...

資料結構與演算法 排序演算法

帶問題思考以下幾點 1 每個演算法的思想是什麼?2 每個演算法的穩定性怎樣?時間複雜度是多少?3 在什麼情況下,演算法出現最好情況 or 最壞情況?4 每種演算法的具體實現又是怎樣的?n每次選擇乙個元素k插入到之前已排好序的部分a 1 i 中,插入過程中k依次由後向前與a 1 i 中的元素進行比較。...

資料結構與演算法(五)

雙端鍊錶和雙向鍊錶 一.雙端鍊錶 1.什麼是雙端鍊錶 鍊錶中儲存著對最後乙個鏈結點的引用的鍊錶 2.從頭部進行插入 要對鍊錶進行判斷,如果為空則設定尾結點為新新增的結點。3.從尾部進行插入 如果鍊錶為空,則直接設定頭結點為新新增的結點,否則設定尾結點的後乙個結點為新新增的結點。4.從頭部進行刪除 判...