本節將兩種交換排序氣泡排序和快速排序
氣泡排序是最簡單的交換排序方法,比較相鄰兩個記錄的關鍵字,將大的放到右邊,小的放到左邊,如圖所示:
從而使關鍵字小的左移、大的右移;每一次迴圈最右邊的必定是關鍵字最大的元素,外面再加一層迴圈即可得到有序序列。
**實現:
#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競賽 以及其他領域中經常被用到 接下來,我們先看一看氣泡排序。氣泡排序基本思想 通過無序區中相鄰記錄關鍵字間的比較和位置的交換,使關鍵字最小的記錄如氣泡一般逐漸往上 漂浮 直至 水...