日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

几种排序算法的认识

發(fā)布時(shí)間:2025/4/5 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 几种排序算法的认识 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

所有排序算法總結(jié):冒泡排序,快速排序,插入排序,歸并排序,堆排序,shell排序,選擇排序

算法排序的穩(wěn)定性是指:關(guān)鍵碼相同的記錄排序前后相對(duì)位置不發(fā)生改變。舉個(gè)例子:

待排序數(shù)組:int a[] ={1, 2, 2, 3, 4, 5, 6};

在快速排序的隨機(jī)選擇比較子(即pivot)階段:

若選擇a[2](即數(shù)組中的第二個(gè)2)為比較子,,而把大于等于比較子的數(shù)均放置在大數(shù)數(shù)組中,則a[1](即數(shù)組中的第一個(gè)2)會(huì)到pivot的右邊, 那么數(shù)組中的兩個(gè)2非原序(這就是“不穩(wěn)定”)。

若選擇a[1]為比較子,而把小于等于比較子的數(shù)均放置在小數(shù)數(shù)組中,則數(shù)組中的兩個(gè)2順序也非原序。

1. 冒泡排序

  很簡單的排序,外層循環(huán)是n-1趟,內(nèi)層循環(huán)是n-1次兩兩比較。主要思路:從底部往上冒泡,通過無序區(qū)中相鄰記錄關(guān)鍵字間的比較和位置的交換,使關(guān)鍵字最小的記錄如氣泡一般逐漸往上“漂浮”直至“水面”。

就是在每一趟內(nèi)層循環(huán)完畢之后,最小的那個(gè)值會(huì)像氣泡一樣上浮到第一個(gè)位置(從小到大排序),這樣循環(huán)執(zhí)行n-1趟,每一趟都是從最后一個(gè)值開始進(jìn)行兩兩比較,把每趟中的最小的值往上浮。(注意內(nèi)層循環(huán)的終止條件是j>i,因?yàn)閕之前是已經(jīng)放置好的有序的最小值

代碼:

static void bubblesort(int* A,int n){if(A==NULL) return;for (int i=0;i<n-1;++i){for (int j=n-1;j>i;--j){if(A[j]<A[j-1]){int temp=A[j];A[j]=A[j-1];A[j-1]=temp;}}cout<<""<<i+1<<"趟冒泡排序:"<<endl;for (int i=0;i<n;++i){cout<<A[i]<<" ";}cout<<endl;} }

?

2. 歸并排序(穩(wěn)定,效率高,采用遞歸)

  思路:基本思路就是將數(shù)組分成二組A,B,如果這二組組內(nèi)的數(shù)據(jù)都是有序的,那么就可以很方便的將這二組數(shù)據(jù)進(jìn)行排序。問題是如何讓這二組組內(nèi)數(shù)據(jù)有序呢?

  可以將A,B組各自再分成二組。依次類推,當(dāng)分出來的小組只有一個(gè)數(shù)據(jù)時(shí),可以認(rèn)為這個(gè)小組組內(nèi)已經(jīng)達(dá)到了有序,然后再合并相鄰的二個(gè)小組就可以了。這樣通過先遞歸的分解數(shù)列,再合并數(shù)列就完成了歸并排序。具體過程參考下圖:

代碼(先用遞歸分解數(shù)組,然后用mergearray合并):

//將有二個(gè)有序數(shù)列a[first...mid]和a[mid...last]合并。 void mergearray(int a[], int first, int mid, int last, int temp[]) {int i = first, j = mid + 1;//i為分出的第一個(gè)數(shù)組的第一個(gè)位置,j為分出來的第二個(gè)數(shù)組的第一個(gè)位置int m = mid,n = last;//m為分出的第一個(gè)數(shù)組的末尾,n為分出來的第二個(gè)數(shù)組的末尾int k = 0;while (i <= m && j <= n){if (a[i] <= a[j])temp[k++] = a[i++];elsetemp[k++] = a[j++];}while (i <= m)temp[k++] = a[i++];while (j <= n)temp[k++] = a[j++];for (i = 0; i < k; i++)a[first + i] = temp[i]; } void mergesort(int a[], int first, int last, int temp[]) {if (first < last){int mid = (first + last) / 2;mergesort(a, first, mid, temp); //左邊有序mergesort(a, mid + 1, last, temp); //右邊有序mergearray(a, first, mid, last, temp); //再將二個(gè)有序數(shù)列合并 } }bool MergeSort(int a[], int n) {int *p = new int[n];if (p == NULL)return false;mergesort(a, 0, n - 1, p);delete[] p;return true; }

?

3.?堆排序(轉(zhuǎn)http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html)

1.堆

??堆實(shí)際上是一棵完全二叉樹,其任何一非葉節(jié)點(diǎn)滿足性質(zhì):

? Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]

? 即任何一非葉節(jié)點(diǎn)的關(guān)鍵字不大于或者不小于其左右孩子節(jié)點(diǎn)的關(guān)鍵字。

? 堆分為大頂堆和小頂堆,滿足Key[i]>=Key[2i+1]&&key>=key[2i+2]稱為大頂堆,滿足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]稱為小頂堆。由上述性質(zhì)可知大頂堆的堆頂?shù)年P(guān)鍵 字肯定是所有關(guān)鍵字中最大的,小頂堆的堆頂?shù)年P(guān)鍵字是所有關(guān)鍵字中最小的。

2.堆排序的思想

?? 利用大頂堆(小頂堆)堆頂記錄的是最大關(guān)鍵字(最小關(guān)鍵字)這一特性,使得每次從無序中選擇最大記錄(最小記錄)變得簡單。

??? 其基本思想為(大頂堆):

??? 1)將初始待排序關(guān)鍵字序列(R1,R2....Rn)構(gòu)建成大頂堆,此堆為初始的無序區(qū);

??? 2)將堆頂元素R[1]與最后一個(gè)元素R[n]交換,此時(shí)得到新的無序區(qū)(R1,R2,......Rn-1)和新的有序區(qū)(Rn),且滿足R[1,2...n-1]<=R[n];?

??? 3)由于交換后新的堆頂R[1]可能違反堆的性質(zhì),因此需要對(duì)當(dāng)前無序區(qū)(R1,R2,......Rn-1)調(diào)整為新堆,然后再次將R[1]與無序區(qū)最 后一個(gè)元素交換,得到新的無序區(qū)(R1,R2....Rn-2)和新的有序區(qū)(Rn-1,Rn)。不斷重復(fù)此過程直到有序區(qū)的元素個(gè)數(shù)為n-1,則整個(gè)排 序過程完成。

??? 操作過程如下:

???? 1)初始化堆:將R[1..n]構(gòu)造為堆;

???? 2)將當(dāng)前無序區(qū)的堆頂元素R[1]同該區(qū)間的最后一個(gè)記錄交換,然后將新的無序區(qū)調(diào)整為新的堆。

??? 因此對(duì)于堆排序,最重要的兩個(gè)操作就是構(gòu)造初始堆和調(diào)整堆,其實(shí)構(gòu)造初始堆事實(shí)上也是調(diào)整堆的過程,只不過構(gòu)造初始堆是對(duì)所有的非葉節(jié)點(diǎn)都進(jìn)行調(diào)整。

????下面舉例說明:

???? 給定一個(gè)整形數(shù)組a[]={16,7,3,20,17,8},對(duì)其進(jìn)行堆排序。

??? 首先根據(jù)該數(shù)組元素構(gòu)建一個(gè)完全二叉樹,得到

?然后需要構(gòu)造初始堆,則從最后一個(gè)非葉節(jié)點(diǎn)開始調(diào)整,調(diào)整過程如下:

20和16交換后導(dǎo)致16不滿足堆的性質(zhì),因此需重新調(diào)整

這樣就得到了初始堆。

即每次調(diào)整都是從父節(jié)點(diǎn)、左孩子節(jié)點(diǎn)、右孩子節(jié)點(diǎn)三者中選擇最大者跟父節(jié)點(diǎn)進(jìn)行交換(交換之后可能造成被交換的孩子節(jié)點(diǎn)不滿足堆的性質(zhì),因此每次交換之后要重新對(duì)被交換的孩子節(jié)點(diǎn)進(jìn)行調(diào)整)。有了初始堆之后就可以進(jìn)行排序了。

此時(shí)3位于堆頂不滿堆的性質(zhì),則需調(diào)整繼續(xù)調(diào)整

這樣整個(gè)區(qū)間便已經(jīng)有序了。 從上述過程可知,堆排序其實(shí)也是一種選擇排序,是一種樹形選擇排序。只不過直接選擇排序中,為了從R[1...n]中選擇最大記錄,需比較n-1次,然后 從R[1...n-2]中選擇最大記錄需比較n-2次。事實(shí)上這n-2次比較中有很多已經(jīng)在前面的n-1次比較中已經(jīng)做過,而樹形選擇排序恰好利用樹形的 特點(diǎn)保存了部分前面的比較結(jié)果,因此可以減少比較次數(shù)。對(duì)于n個(gè)關(guān)鍵字序列,最壞情況下每個(gè)節(jié)點(diǎn)需比較log2(n)次,因此其最壞情況下時(shí)間復(fù)雜度為 nlogn。堆排序?yàn)椴环€(wěn)定排序,不適合記錄較少的排序。 測試程序 /*堆排序(大頂堆) 2011.9.14*/

#include <iostream>
#include<algorithm>
using namespace std;

void HeapAdjust(int *a,int i,int size) //調(diào)整堆
{
int lchild=2*i; //i的左孩子節(jié)點(diǎn)序號(hào)
int rchild=2*i+1; //i的右孩子節(jié)點(diǎn)序號(hào)
int max=i; //臨時(shí)變量
if(i<=size/2) //如果i是葉節(jié)點(diǎn)就不用進(jìn)行調(diào)整
{
if(lchild<=size&&a[lchild]>a[max])
{
max=lchild;
}
if(rchild<=size&&a[rchild]>a[max])
{
max=rchild;
}
if(max!=i)
{
swap(a[i],a[max]);
HeapAdjust(a,max,size); //避免調(diào)整之后以max為父節(jié)點(diǎn)的子樹不是堆
}
}
}

void BuildHeap(int *a,int size) //建立堆
{
int i;
for(i=size/2;i>=1;i--) //非葉節(jié)點(diǎn)最大序號(hào)值為size/2
{
HeapAdjust(a,i,size);
}
}

void HeapSort(int *a,int size) //堆排序
{
int i;
BuildHeap(a,size);
for(i=size;i>=1;i--)
{
//cout<<a[1]<<" ";
swap(a[1],a[i]); //交換堆頂和最后一個(gè)元素,即每次將剩余元素中的最大者放到最后面
//BuildHeap(a,i-1); //將余下元素重新建立為大頂堆
HeapAdjust(a,1,i-1); //重新調(diào)整堆頂節(jié)點(diǎn)成為大頂堆
}
}

int main(int argc, char *argv[])
{
//int a[]={0,16,20,3,11,17,8};
int a[100];
int size;
while(scanf("%d",&size)==1&&size>0)
{
int i;
for(i=1;i<=size;i++)
cin>>a[i];
HeapSort(a,size);
for(i=1;i<=size;i++)
cout<<a[i]<<"";
cout<<endl;
}
return 0;
}
4.快速排序 思路:主要patition函數(shù)的編寫,即先選一個(gè)值作為哨兵,然后把小于該哨兵的數(shù)字放在其左邊(后稱左邊序列),然后把大于哨兵的數(shù)字放在右邊(后稱右邊序列)。該函數(shù)有幾種實(shí)現(xiàn)方法,請(qǐng)參見http://www.cnblogs.com/mfryf/archive/2012/08/06/2625300.html   該函數(shù)用small指針來表示左邊序列的最后一個(gè)位置,當(dāng)發(fā)現(xiàn)某個(gè)值A(chǔ)[i]小于哨兵時(shí),只需先對(duì)該small指針后移一位(移到右邊序列的第一位),然后將A[small]和A[i]互換即可,換完之后,small指針仍然指向左邊序列最后一個(gè)位置。   所以說,數(shù)組A,在進(jìn)行一輪快速排序的時(shí)候,實(shí)際上有一個(gè)哨兵和三個(gè)序列,左邊序列,右邊序列,待排序列。 具體如圖所示: 5.直接插入排序(最好O(n),最壞O(n2))參考博文   思路:把一個(gè)序列分為兩個(gè)區(qū),前部分是已排好的序列sorted,而后部分則是待排序列wait_sort,插入排序就是選擇wait_sort中的第一個(gè)元素,直接插入到sorted序列中。   假設(shè)要插入元素a[i],則插入的步驟分為3步:1>在sorted序列中找到要插入元素的位置j。2>將位置j之后的序列往后移動(dòng)一位,給帶插入的a[i]空出一個(gè)位置。3>把元素a[i]插入到sorted序列中。

設(shè)數(shù)組為a[0…n-1]。

1.????? 初始時(shí),a[0]自成1個(gè)有序區(qū),無序區(qū)為a[1..n-1]。令i=1

2.????? 將a[i]并入當(dāng)前的有序區(qū)a[0…i-1]中形成a[0…i]的有序區(qū)間。

3.????? i++并重復(fù)第二步直到i==n-1。排序完成。

?

下面給出嚴(yán)格按照定義書寫的代碼(由小到大排序):

void Insertsort1(int a[], int n) {int i, j, k;for (i = 1; i < n; i++){//為a[i]在前面的a[0...i-1]有序區(qū)間中找一個(gè)合適的位置for (j = i - 1; j >= 0; j--)if (a[j] < a[i])break;//如找到了一個(gè)合適的位置if (j != i - 1){//將比a[i]大的數(shù)據(jù)向后移int temp = a[i];for (k = i - 1; k > j; k--)a[k + 1] = a[k];//將a[i]放到正確位置上a[j+1] = temp;}} }

  

  這樣的代碼太長了,不夠清晰。現(xiàn)在進(jìn)行一下改寫,將搜索和數(shù)據(jù)后移這二個(gè)步驟合并。即每次a[i]先和前面一個(gè)數(shù)據(jù)a[i-1]比較,如果a[i] > a[i-1]說明a[0…i]也是有序的,無須調(diào)整。否則就令j=i-1,temp=a[i]。然后一邊將數(shù)據(jù)a[j]向后移動(dòng)一邊向前搜索,當(dāng)有數(shù)據(jù)a[j]<a[i]時(shí)停止并將temp放到a[j + 1]處。

void Insertsort2(int a[], int n) {int i, j;for (i = 1; i < n; i++)if (a[i] < a[i - 1]){int temp = a[i];for (j = i - 1; j >= 0 && a[j] > temp; j--)a[j + 1] = a[j];a[j + 1] = temp;} }

?


?

轉(zhuǎn)載于:https://www.cnblogs.com/fightformylife/p/4335390.html

總結(jié)

以上是生活随笔為你收集整理的几种排序算法的认识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久草综合在线视频 | 亚洲一区二区影院 | 亚洲成在人 | 国产免费久久精品国产传媒 | 国产精品性爱在线 | 成人极品| av官网在线 | 亚州综合| 久久91精品国产91久久小草 | 动漫av在线 | 黑人巨大国产9丨视频 | 亚洲最大福利 | 国产精品无码免费在线观看 | xxx国产| 韩国甜性涩爱 | 男人资源网站 | 欧美精品日韩在线观看 | 一级视频在线播放 | 九九操 | 在线aaa| 久久免费福利视频 | www.黄色在线 | 大陆av在线播放 | 国产成人精品综合在线观看 | 男人捅爽女人 | 91一区二区 | 日本成人免费在线 | 强行糟蹋人妻hd中文字幕 | 午夜操一操 | 亚洲五月激情 | 日本精品视频一区 | 色综合久久88色综合天天6 | 国产毛片久久久久久久 | 欧美综合一区 | 精品动漫一区二区三区的观看方式 | jav中文字幕 | 国产成人精品综合 | 亚洲精品2 | 日韩一卡二卡在线 | 亚洲成人播放器 | 国产小视频在线看 | 老司机精品福利导航 | 四虎永久免费影院 | 丁香色婷婷 | 中文字幕淫 | 性欧美又大又长又硬 | 先锋av资源网 | 翔田千里一区二区三区av | 男女黄床上色视频 | 性欧美成人播放77777 | 久久精品国产亚洲av成人 | 欧日韩一区二区三区 | 国产午夜精品一区二区三区欧美 | 午夜爽爽影院 | 99亚洲国产精品 | 欧美成人看片黄a免费看 | 亚洲另类视频 | 美女午夜视频 | 亚洲免费网站在线观看 | 精品一二三四区 | youjizz亚洲| 蜜桃av成人 | 国产一区精品视频 | 国产片91 | 国产最新在线视频 | 国产在线观看免费视频软件 | 不用播放器的av网站 | 调教在线观看 | 成人91看片 | 成人福利网站在线观看 | 国产一精品一aⅴ一免费 | 97福利社 | 亚洲高清在线免费观看 | 欧美 日韩 国产精品 | 在线观看免费的av | 国产盗摄一区二区三区 | 男女午夜激情视频 | 日韩av在线一区 | 高清久久久久久 | 亚洲欧美日韩成人在线 | 打美女白嫩屁屁网站 | 国产精品一区二区亚洲 | 女优色图 | 国产色无码精品视频 | 99极品视频 | 日日干夜夜艹 | 亚洲影视一区二区三区 | 国产盗摄一区二区三区在线 | 欧洲高潮三级做爰 | 国产成人av在线播放 | 日韩精品视频免费在线观看 | 成人欧美一区二区三区黑人免费 | 欧美无遮挡高潮床戏 | 大又大粗又爽又黄少妇毛片 | 激情亚洲色图 | 欧美久久成人 | 91久久精品日日躁夜夜躁欧美 | 久久久久久久久久免费视频 | 激情内射亚洲一区二区三区爱妻 |