學習 排序演算法 快排 選擇 冒泡 桶排序

2021-10-10 21:40:20 字數 3914 閱讀 6800

稍微複習(+學習)了一下排序的演算法:選擇/冒泡/桶/快排等

下面的**和講解也是這幾種排序,至於歸併/基數啥的想單獨開一篇部落格

以下單獨**均涉及巨集定義,可以先看思路再到最後看巨集定義內容

本部落格針對洛谷p1177排序模板 並已通過大資料對拍 為公升序排序

快速排序

stl**好,直接sort

想降序可以手寫cmp或者倒序輸出

fo

(i,1

,n) num[i]

=read()

;sort

(num+

1,num+n+1)

;fo(i,1

,n)printf

("%d "

,num[i]

);

降序cmp寫法

bool

cmp(

int a ,

int b)

選擇排序

顧名思義就是每次都選擇我需要的那個數放在一遍,重複n次

每次我假定第i個值最小,然後我迴圈從i+1到n,如果有比我小的我就記錄下來,並且記錄這個位置,當我把i+1後面所有的值都迴圈完之後,我找到了最小的值,交換最小的值和i位置上的值,所以i位置目前放的就是最小的,然後將i迴圈起來,就可以公升序排序。

void

xz_sort()

swap

(num[min_op]

,num[i]);

}}

選擇排序的優化

每次只選最小值還是有點浪費時間的,我倒不如每次都選擇最大值和最小值,然後把最大值放在最後最小值放在最前面。注意這裡的最後和最前是還沒排序好的,如果已經確定了就不要再修改了。這樣的話我們的i就沒必要迴圈到n了,就省下了一部分時間。

坑點:小心**中continue的兩種情況均是「最小值在最後的情況」:1.最大值在最前面,最小值在最後面,交換一次就可以了 2.最小值在最後,最大值不是最前面,所以最小值要與原來最大值的位置互換。

void

x_sort()

if(num[j]

>maxx)}if

(i==max_op&&n-i+

1==min_op)

swap

(num[n-i+1]

,num[max_op]);

if(min_op==n-i+1)

swap

(num[i]

,num[min_op]);

}}

氣泡排序

所謂氣泡排序,就是像冒泡一樣,數的大小模擬為泡的輕重。

每乙個數從頭迴圈到n-i,i的意思是已經有i個數排好序,這樣每次遇到後面比前面小就互換,最大的一定在最後吧,這樣做1次就有1個數到他自己應該去的地方,一共迴圈n次就把所有的數放到應該放的位置,就完成了排序。

void

m_sort()

氣泡排序的優化

就是如果i還沒迴圈完就已經排好序了,後面是不是不用再排序了。用乙個變數flag記錄是否還在排序,從而判斷是否結束迴圈。

void

mp_sort()

if(!flag)

break;}

}

桶排序

用乙個桶把所有的數出現的次數記錄下來,然後i從1到最大值開始迴圈,如果發現出現過(出現次數不為0)就輸出,出現幾次就輸出幾次,這樣輸出就能排好序。數比較小,可以直接用陣列儲存。

int cnt[l]

;void

t_sort()

fo(i,

1,maxx)

if(cnt[i])fo

(j,1

,cnt[i]

)printf

("%d "

,i);

}

桶排序的優化

陣列當然不能滿足我們的要求,所以考慮用map實現對大數的存放

(突然想起來上次決定要補的map鴿了)

mappot;

void

tp_sort()

fo(i,

1,top)

printf

("%d "

,cnt[i]);

}

總的**實現

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

#define pi acos(-1)

#define fin freopen("data.txt","r",stdin)

#define inf 2147483647

#define eps 1e-7

#define l 100005

#define fo(i,a,b) for(ll i=(a),_=(b); i<=_; i++)

#define ro(i,b,a) for(ll i=(b),_=(a); i>=_; i--)

inline ll read()

while

(isdigit

(c)) x=

(x<<1)

+(x<<3)

+(c^

48ll

),c=

getchar()

;return x*f;

}mappot;

int num[l]

, n , minn , maxx , min_op , max_op , flag , cnt[l]

, top;

bool

cmp(

int a ,

int b)

void

xz_sort()

swap

(num[min_op]

,num[i]);

}}void

x_sort()

if(num[j]

>maxx)}if

(i==max_op&&n-i+

1==min_op)

swap

(num[n-i+1]

,num[max_op]);

if(min_op==n-i+1)

swap

(num[i]

,num[min_op]);

}}void

m_sort()

void

mp_sort()

if(!flag)

break;}

}void

t_sort()

fo(i,

1,maxx)

if(cnt[i])fo

(j,1

,cnt[i]

)printf

("%d "

,i);

}void

tp_sort()

fo(i,

1,top)

printf

("%d "

,cnt[i]);

}int

main()

已經有nlogn的sort然後再學這些排序的原因呢,是得了解原理啊

反正好多題都是這些原理改的(現在突然想起來做過乙個桶排序的推廣題)

好了,就這,祝你能看懂。

排序 選擇 冒泡 快排

簡單介紹三種常見的排序方法 選擇 冒泡 快排。從大到小排列 選擇排序是在所有資料中先選擇第乙個資料作為最大值,依次和後面的每乙個資料比較,如果比最大值大,替換最大值並且記住索引,遍歷結束後,通過索引把最大值和第乙個資料替換。後面的資料依次執行一遍,就可以得到從大到小排列的資料了。如下 4 void ...

排序專題(桶排序,冒泡,快排,堆排序)

1.最簡單的排序 桶排序 簡化版 優點 快速,簡單 缺點 資料足夠大時,會造成嚴重的空間浪費 不能解決小數問題 理解 桶排序就是開乙個足夠大的陣列,陣列下標最大值 設為x,a x 要大於需要排序的資料最大值。設輸入為ni,則只要令a ni 就可以確定相同ni的個數,然後從從0到n,只要a ni 不為...

演算法的效率(氣泡排序 選擇排序 快排)

演算法的效率可以用 時間複雜度o n 來度量。時間複雜度反應了程式執行時間隨輸入規模增長而增長的量級,很大程度上能反應演算法的優略程度。我們最開始認識的排序方法有氣泡排序和選擇排序但是這個演算法的效率怎麼樣呢,讓我們來測試一下。首先,我們隨機生成乙個長度為100000的隨機數組,並選用選擇排序的方法...