資料結構 排序之交換排序

2021-09-02 17:34:58 字數 4025 閱讀 3484

本節將兩種交換排序氣泡排序和快速排序

氣泡排序是最簡單的交換排序方法,比較相鄰兩個記錄的關鍵字,將大的放到右邊,小的放到左邊,如圖所示:

從而使關鍵字小的左移、大的右移;每一次迴圈最右邊的必定是關鍵字最大的元素,外面再加一層迴圈即可得到有序序列。

**實現:

#include using namespace std;

#define maxsize 100

typedef int keytype;

typedef struct///定義每個節點資訊

rtype;

typedef struct///定義順序表

sqlist;

void bubblesort(sqlist &l)

}if(flag)break; ///當flag為1時,表明序列已經有序,可以結束迴圈

}}int main()

bubblesort(l);

for(int i = 1; i <= l.length; i ++)

return 0;

}/***

1070 30 52 29 50 62 49 86 2 13

***/

複雜度分析:

時間複雜度為o(n^2),空間複雜度為o(1)。

補:氣泡排序的交換次數即數列的逆序對數。

二、快速排序(quick sort)

之所以稱其為快速排序,他快嘛!(一般(nlog n)就可以解決問題甚至更快)

大體思想:序列r[1...n]

a.選取序列中乙個元素作為標桿x(或者標記,怎麼記都行,╮(╯▽╰)╭),一般選取第乙個元素。

b.遍歷序列中的元素,將比x小的元素放置x的左邊,比x的元素放置x的右邊。

c.然後用與a、b同樣的分別操作處理x左邊和右邊的序列。

先感性理解一下ε=(´ο`*))),

看起來有沒有像二分

我們先看圖說話o(∩_∩)o哈哈~

我們假定排序的是一段區間r[left...right],x選定為區間第乙個元素x=r[left]

由經過操作b,我們知道,標桿x左邊的元素都比他小,標桿右邊的元素都比他大(當然如何將小的移到左邊、大的移到右邊,需要一些技巧,我們先不管o(∩_∩)o~~,稍後接著說說如何實現)

將標桿所在序列位置記為mid(名義上的,並不是真正意義上的mid,不要在意(#^.^#)),然後就可以最區間r[left, mid-1]r[mid+1, right]進行同樣的操作。

經過上面的分析,一頓操作猛如虎,突然發現可以用遞迴實現。

萬事俱備,只差如何實現操作b了,來薛薇的說說

隨機給定乙個序列: 70   30   52   29   50   62   49    86    2    13 

我們繼續看圖說話,

x = r[left = 1] = 70,r[0] = r[left](將r[0]空出來,方便操作)

left = 1的位置空了,從right = 10開始向左遍歷,直到有小於x的元素,r[right = 10] = 13 < x,將13賦值給r[left], left加一;

現在right = 10的位置也空了,從left = 2向右遍歷,直到有大於x的元素,此時當left = 8到達元素86(>x)所在位置,將86賦值給r[right = 10],right減一;

此時left = 8的位置又空了o(╥﹏╥)o,再從right = 9向左遍歷,直到有小於x的元素,r[right = 9] = 2 < x,將2賦值給r[left = 8],left加一 。

此時left  = right = 9,第一趟排序結束,將r[left]x填上,用mid記一下left的位置。

然後就同理處理區間r[left...mid-1]r[mid+1, right]了。

注意當區間只有乙個元素時,貌似就不用處理了吧,恩,對的。

5趟排序就完事了。

補上**:

#include using namespace std;

#define maxsize 100

typedef int keytype;

typedef struct///定義每個節點資訊

rtype;

typedef struct///定義順序表

sqlist;

int partition(sqlist &l, int left, int right)

l.r[left] = l.r[0];

return left;

}void qsort(sqlist &l, int left, int right)

}void quicksort(sqlist &l)

int main()

quicksort(l);

for(int i = 1; i <= l.length; i ++)

printf("\n");

return 0;

}/**

1070 30 52 29 50 62 49 86 2 13

**/

再來分析一下**。看起來有二分的思想,但不完全是二分,因為每次x不上的位置不完全是中間位置,但可以近似的看成是二分,所以平均時間複雜度為o(nlog n),但也存在某些特殊的串行使時間複雜度算退化為o(n^2),也由此可見此演算法不太穩定。不過不用太擔心,一般情況不會遇到那些特殊的序列。由於是用遞迴實現的所以其空間複雜度不是o(1),大致是o(log n)。補充:

在c和c++裡面都有寫好的快速排序函式,可以直接呼叫

額,(⊙o⊙)…大家還是看其他大佬的部落格吧

c語言的:

c++ 的:

資料結構排序系列之交換排序(二)

交換排序我們介紹氣泡排序和快速排序 劃分交換排序 核心思想就是通過元素兩兩比較,發現反序時進行交換,直到所有元素都沒有反序為止。演算法思想 通過相鄰元素之間的比較和交換來完成。氣泡排序從後往前,進行相鄰元素的兩兩比較和交換。使關鍵字小的元素逐漸從底部移向頂部。演算法實現 include r為待排序的...

資料結構演算法 排序演算法之交換排序 快速排序

快速排序 1 設定兩個 變數i j,排序開始的時候 i 0,j n 1 2 以第乙個 陣列元素作為關鍵資料,賦值給key,即key a 0 3 從j開始向前搜尋,即由後開始向前搜尋 j 找到第乙個小於key的值a j 將a j 和a i 互換 4 從i開始向後搜尋,即由前開始向後搜尋 i 找到第乙個...

排序專題之交換排序

在交換排序這一類中,分為氣泡排序和快速排序,快速排序是建立在 氣泡排序基礎上的乙個優化,很有意義的乙個排序,在各種acm競賽 以及其他領域中經常被用到 接下來,我們先看一看氣泡排序。氣泡排序基本思想 通過無序區中相鄰記錄關鍵字間的比較和位置的交換,使關鍵字最小的記錄如氣泡一般逐漸往上 漂浮 直至 水...