各種排序算法總結

轉載:http://blog.csdn.net/warringah1/article/details/8951220

明天就要去參加阿里巴巴的實習生筆試了,雖然沒想著能進去,但是態度還是要端正的,也沒什么可以準備的,復習復習排序吧。

1 插入排序

void?InsertSort(int?a[],?int?n)

{

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

????????????int?key?=?a[i];

????????????int?j?=?i?- 1;

????????????while(j>=0 &&?a[j]>key) {

??????????????????a[j+1] =?a[j];

????????????????? --j;

??????????? }

????????????a[j+1] =?key;

????? }

}

插入排序是穩定的排序,平均和最壞時間復雜度是O(n^2)。最好的時間復雜度是O(n),對應于全部排好序的情況。

?

2 冒泡排序

void?BubbleSort(int?a[],?int?n)

{

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

????????????for(int?j=0;?j<n-i; ++j) {

??????????????????if(a[j]>a[j+1]) {

???????????????????????inttemp?=?a[j];

???????????????????????a[j] =?a[j+1];

???????????????????????a[j+1] =?temp;

????????????????? }

??????????? }

????? }

}

冒泡排序是穩定的排序,平均和最壞時間復雜度是O(n^2)。

?

3 選擇排序

每一趟從待排序的數據元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最后,直到全部待排序的數據元素排完。選擇排序是不穩定的排序方法。

void?SelectSort(int?a[],?int?n)

{

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

????????????for(int?j=i+1;?j<n; ++j) {

??????????????????if(a[i]>a[j]) {

???????????????????????inttemp?=?a[i];

???????????????????????a[i] =?a[j];

???????????????????????a[j] =?temp;

????????????????? }

??????????? }

????? }

}

選擇排序是不穩定的,因為,在一趟選擇,如果當前元素比一個元素小,而該小的元素又出現在一個和當前元素相等的元素后面,那么交換后穩定性就被破壞了。舉個例子,序列5 8 5 2 9,我們知道第一遍選擇第1個元素5會和2交換,那么原序列中2個5的相對前后順序就被破壞了平均和最壞時間復雜度是O(n^2)。

?

4 希爾排序(縮小增量排序)

該方法的基本思想是:先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然后依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。因為直接插入排序在元素基本有序的情況下(接近最好情況),效率是很高的,因此希爾排序在時間效率上比前兩種方法有較大提高。

void?ShellSort(int?a[],?int?n)

{

??????for?(int?gap=n/2;?gap>0;?gap/=2) {

????????????for(int?i=0;?i<gap; ++i) {

??????????????????for(int?j=i+gap;?j<n;?j+=gap) {

???????????????????????if(a[j]<a[j-gap]) {

?????????????????????????????int?temp?=?a[j];

?????????????????????????????int?k?=?j-gap;

?????????????????????????????while?(k>=0&&a[k]>temp) {

???????????????????????????????????a[k+gap] =?a[k];

?????????????????????? ????????????k?-=?gap;

???????????????????????????? }

?????????????????????????????a[k+gap] =?temp;

?????????????????????? }

????????????????? }

??????????? }

????? }

}

?

void?ShellSortImproved(int?a[],?int?n)

{

??????for?(int?gap=n/2;?gap>0;?gap/=2) {

????????????for(int?j=gap;?j<n; ++j) {

??????????????????if(a[j]<a[j-gap]) {

???????????????????????inttemp?=?a[j];

???????????????????????intk?=?j?-?gap;

???????????????????????while(k>=0 &&?a[k]>temp) {

?????????????????????????????a[k+gap] =?a[k];

?????????????????????????????k?-=?gap;

?????????????????????? }

???????????????????????a[k+gap] =?temp;

????????????????? }

??????????? }

????? }

}

希爾排序是不穩定的。由于多次插入排序,我們知道一次插入排序是穩定的,不會改變相同元素的相對順序,但在不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,最后其穩定性就會被打亂,所以shell排序是不穩定的。使用希爾增量時,最壞運行時間是O(n^2),使用Hibbard增量時,最壞運行時間是O(n^3/2)。

?

5. 堆排序

void?MaxHeapify1(int?a[],?int?n,?int?i)

{

??????int?l?=?LEFT(i);

??????int?r?=?RIGHT(i);

??????int?largest;

??????if?(l<n&&?a[l]>a[i])

????????????largest=?l;

??????else

????????????largest=?i;

??????if?(r<n&&?a[r]>a[largest])

????????????largest=?r;

??????if?(largest!=i) {

????????????swap(a[i],?a[largest]);

????????????MaxHeapify1(a,?n,?largest);

????? }?else

????????????return;

}

?

void?MaxHeapify2(int?a[],?int?n,?int?i)

{

??????int?c,??largest;

??????while?(1){

????????????c=?LEFT(i);

????????????if?(c>=n)

??????????????????break;

????????????if?(a[i]<a[c])

??????????????????largest=?c;

????????????else

??????????????????largest=?i;

????????????if?(c+1<n) {

??????????????????if(a[largest]<a[c+1])

???????????????????????largest=?c?+ 1;

??????????? }

????????????if?(largest!=i) {

??????????????????swap(a[i],?a[largest]);

??????????????????i=?largest;

??????????? }?else

??????????????????break;

????? }

}

?

void?HeapSort(int?a[],?int?n)

{

??????for?(int?i=n/2-1;?i>=0;--i)

????????????MaxHeapify1(a,?n,?i);

??????for?(int?i=n-1;?i>0; --i) {

????????????swap(a[i],?a[0]);

????????????MaxHeapify1(a,?i, 0);

????? }

}

堆排序是原地排序,但是不是穩定排序。時間復雜度O(nlogn)。

?

6 歸并排序

void?Merge(int?a[],?int?p,?int?q,?int?r)

{

??????int?n1?=?q?-?p?+ 1;

??????int?n2?=?r?- (q+1) +1;

?

??????int?*L?=?new?int[n1+1];

??????int?*R?=?new?int[n2+1];

?

??????for?(int?i=0;?i<n1; ++i)

????????????L[i] =?a[p+i];

??????for?(int?i=0;?i<n2; ++i)

????????????R[i] =?a[q+1+i];

??????L[n1] =?INT_MAX;//哨兵

??????R[n2] =?INT_MAX;

??????int?i?= 0,?j?= 0;

??????for?(int?k=p;?k<=r; ++k) {

????????????if?(L[i]<=R[j])

??????????????????a[k] =?L[i++];

????????????else

??????????????????a[k] =?R[j++];

????? }

??????delete[]?L;

??????delete[]?R;

}

?

void?MergeSort(int?a[],?int?p,?int?r)

{

??????if?(p<r) {;

????????????int?q?= ((r-p)>>1) +?p;

????????????MergeSort(a,?p,?q);

????????????MergeSort(a,?q+1,?r);

????????????Merge(a,?p,?q,?r);

????? }

}

合并過程中我們可以保證如果兩個當前元素相等時,我們把處在前面的序列的元素保存在結果序列的前面,這樣就保證了穩定性。所以,歸并排序也是穩定的排序算法。時間復雜度是O(nlogn)。可以在空間復雜度O(1)的條件下實現歸并排序

?

7. 快速排序

被快速排序所使用的空間,依照使用的版本而定。使用原地(in-place)分區的快速排序版本,在任何遞歸調用前,僅會使用固定的額外空間。然而,如果需要產生O(log n)嵌套遞歸調用,它需要在他們每一個存儲一個固定數量的信息。因為最好的情況最多需要O(log n)次的嵌套遞歸調用,所以它需要O(log n)的空間。最壞情況下需要O(n)次嵌套遞歸調用,因此需要O(n)的空間。

void?Median3(int?a[],?int?p,?int?r)

{

??????int?median?=?p?+ ((r-p)>>1);

??????if?(a[p]>a[median])

????????????swap(a[p],?a[median]);

??????if?(a[p]>a[r])

????????????swap(a[p],?a[r]);

??????if?(a[median]>a[r])

????????????swap(a[median],?a[r]);

??????swap(a[median],?a[r]);

}

?

int?Partition1(int?a[],?int?p,?int?r)

{

??????Median3(a,?p,?r);

??????int?x?=?a[r];

??????int?i?=?p?- 1;

??????for?(int?j=p;?j<=r-1; ++j) {

????????????if?(a[j]<=x) {

????????????????? ++i;

??????????????????swap(a[i],?a[j]);

??????????? }

????? }

??????swap(a[i+1],?a[r]);

??????return?i+1;

}

?

int?Partition2(int?a[],?int?p,?int?r)

{

??????Median3(a,?p,?r);

??????int?i?=?p-1,?j?=?r;

??????int?x?=?a[r];

??????for?(;;) {

????????????while(a[++i]<x);

????????????while(a[--j]>x);

????????????if?(i<j)

??????????????????swap(a[i],?a[j]);

????????????else

??????????????????break;?

????? }

??????swap(a[i],?a[r]);

??????return?i;

}

?

void?QuickSort(int?a[],?int?p,?int?r) {

??????if?(p<r) {

????????????int?q?=?Partition2(a,?p,?r);

????????????QuickSort(a,?p,?q-1);

????????????QuickSort(a,?q+1,?r);

????? }

}

快速排序是不穩定的排序,最差時間復雜度是O(n^2),平均時間復雜度是O(nlogn)。

?

8. 桶排序

void?BucketSort(int?a[],?int?n)

{

??????int?*count?=?new?int[1000];

??????memset(count, 0,?sizeof(int)*1000);

??????for?(int?i=0;?i<n; ++i) {

??????????? ++count[a[i]];

????? }

??????int?k?= 0;

??????for?(int?i=0;?i<1000; ++i){

????????????while(count[i]--){

??????????????????a[k++] =?i;

??????????? }

????? }

}

如果count有M個單元,算法用時O(M+N),桶排序是穩定的排序。但是需要額外的空間。

?

?

穩定的排序有:冒泡,插入,歸并,基數,桶。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259385.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259385.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259385.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CentOS7 上安裝 Zookeeper-3.4.9 服務

在 CentOS7 上安裝 zookeeper-3.4.9 服務1、創建 /usr/local/services/zookeeper 文件夾&#xff1a; mkdir -p /usr/local/services/zookeeper 2、進入到 /usr/local/services/zookeeper 目錄中&#xff1a; cd /usr/local/services/zookeeper 3、下載 zookeeper-3.4.9.…

c語言在程序中顯示現在星期幾,C語言程序設計: 輸入年月日 然后輸出是星期幾...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓#include main(){int year,month,day0,a,b,week,c,i,sum0,days,d;printf("please input year,month,days\n");scanf("%d,%d,%d",&year,&month,&days);for(i1;i{if (year%40){if(year%1000){if (ye…

static之用法

本文轉載于http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html 在C語言中&#xff0c;static的字面意思很容易把我們導入歧途&#xff0c;其實它的作用有三條。 &#xff08;1&#xff09;先來介紹它的第一條也是最重要的一條&#xff1a;隱藏。 當我們同時編譯…

HTTP響應報文與工作原理詳解

HTTP 是一種請求/響應式的協議&#xff0c;即一個客戶端與服務器建立連接后&#xff0c;向服務器發送一個請求;服務器接到請求后&#xff0c;給予相應的響應信息。 超文本傳輸協議(Hypertext Transfer Protocol&#xff0c;簡稱HTTP)是應用層協議。HTTP 是一種請求/響應式的協議…

優先隊列priority_queue 用法詳解

轉載&#xff1a; 1.優先隊列priority_queue 用法詳解 2.STL系列之五 priority_queue 優先級隊列 優先隊列是隊列的一種&#xff0c;不過它可以按照自定義的一種方式&#xff08;數據的優先級&#xff09;來對隊列中的數據進行動態的排序 每次的push和pop操作&#xff0c;隊…

android自定義畫板,android 自定義控件 -- 畫板

如圖&#xff1a;package com.example.myview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Paint.Style;import android.util.Attrib…

postgreSQl pathman 用法語句總結

2019獨角獸企業重金招聘Python工程師標準>>> --新建主表 create table part_test(id int, info text, crt_time timestamp not null); --插入測試數據 insert into part_test select id,md5(random()::text),clock_timestamp() (id|| hour)::interval from generat…

Oracle查詢筆記

-- tanslate(str,from_str,to_str) -- 將str中的from_str替換成to_str select translate(hello,e,o) t from dual;-- instr(str,des_str) -- 可以實現like功能 select instr(hello,g),instr(hello,h),instr(hello,l) from dual; -- decode(value,s1,r1,s2,r2,default) -- 類似于…

全排列算法及實現

轉載&#xff1a; 1.http://blog.csdn.net/hackbuteer1/article/details/6657435 2.http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html 3.http://www.slyar.com/blog/stl_next_permutation.html 4.http://www.cplusplus.com/reference/algorithm/next_permutation/ 5…

ssh配置文件詳解

配置“/etc/ssh/sshd_config”文件 “/etc/ssh/sshd_config”是OpenSSH的配置文件&#xff0c;允許設置選項改變這個daemon的運行。這個文件的每一行包含“關鍵詞&#xff0d;值”的匹配&#xff0c;其中“關鍵詞”是忽略大小寫的。下面列出來的是最重要的關鍵詞&#xff0…

EC+VO+SCOPE for ES3

詞法環境 詞法作用域 詞法作用域&#xff08;lexcical scope&#xff09;。即JavaScript變量的作用域是在定義時決定而不是執行時決定&#xff0c;也就是說詞法作用域取決于源碼。 詞法環境 用于定義特定變量和函數標識符在ECMAScript代碼的詞法嵌套結構上的關聯關系&#xff0…

你真的會寫二分檢索嗎?

轉載&#xff1a;http://blog.chinaunix.net/uid-1844931-id-3337784.html 前幾天在論壇上看到有統計說有80%的程序員不能夠寫對簡單的二分法。二分法不是很簡單的嗎&#xff1f; 這難道不是聳人聽聞&#xff1f; 其實&#xff0c;二分法真的不那么簡單&#xff0c;尤其是二…

android listview動態加載網絡圖片不顯示,Android Listview異步動態加載網絡圖片

Android Listview異步動態加載網絡圖片詳見&#xff1a; http://blog.sina.com.cn/s/blog_62186b460100zsvb.html標簽&#xff1a; Android SDK代碼片段(5)[代碼] (1)定義類MapListImageAndText管理ListViewItem中控件的內容01 package com.google.zxing.client.android.AsyncL…

C#-面向對象的多態思想 ---ShinePans

總結: 多態是面向對象的核心.---------能夠理解為一個方法,多種實現, 在這里能夠用虛方法,抽象類,接口能夠實現多態 1.首先利用接口來實現多態: 接口相當于"功能,"接口能夠實現多繼承,分為 顯式實現接口和隱式實現接口 keyword為interface格式: interface 接口名 { …

wxpy 0.1.2微信機器人 / 優雅的微信個人號API

微信機器人 / 優雅的微信個人號API&#xff0c;基于 itchat&#xff0c;全面優化接口&#xff0c;更有 Python 范兒。用來干啥一些常見的場景控制路由器、智能家居等具有開放接口的玩意兒跑腳本時自動把日志發送到你的微信加群主為好友&#xff0c;自動拉進群中跨號或跨群轉發消…

c++中try catch的用法

在c中&#xff0c;可以直接拋出異常之后自己進行捕捉處理&#xff0c;如&#xff1a;&#xff08;這樣就可以在任何自己得到不想要的結果的時候進行中斷&#xff0c;比如在進行數據庫事務操作的時候&#xff0c;如果某一個語句返回SQL_ERROR則直接拋出異常&#xff0c;在catch塊…

const in c and cpp

http://c-faq.com/ansi/constasconst.html 轉載于:https://www.cnblogs.com/invisible/p/3333575.html

android ndk調用出錯,由于Android-NDK應用程序的權限問題,為什么fopen在本地方法中失敗?...

errno 0;FILE *fp;fp fopen("jigar.txt","wb");if(fp NULL)__android_log_print(ANDROID_LOG_ERROR, APPNAME, "FOPEN FAIL with %d",errno);else__android_log_print(ANDROID_LOG_ERROR, APPNAME, "FOPEN pass ");它得到失敗&…

循環隊列

什么是隊列&#xff1f; 隊列(Queue)也是一種運算受限的線性表。它僅僅同意在表的一端進行插入&#xff0c;而在還有一端進行刪除。同意刪除的一端稱為隊頭(front)&#xff0c;同意插入的一端稱為隊尾(rear)。 FIFO原則 隊列具有先進先出原則&#xff0c;與棧的先進后出形成對照…

T(n) = 25T(n/5)+n^2的時間復雜度 計算方法

對于T(n) a*T(n/b)c*n^k;T(1) c 這樣的遞歸關系&#xff0c;有這樣的結論&#xff1a; if (a > b^k) T(n) O(n^(logb(a)));logb(a)b為底a的對數 if (a b^k) T(n) O(n^k*logn); if (a < b^k) T(n) O(n^k); a25; b 5 ; k2 ab^k 故T(n)O(n^k*logn)O(n^2*logn)…