亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++ 基本算法 冒泡法、交換法、選擇法、實現代碼集合

2020-01-26 16:19:48
字體:
來源:轉載
供稿:網友

1.冒泡法:


這是最原始,也是眾所周知的最慢的算法了。
他的名字的由來因為它的工作看來象是冒泡:

復制代碼 代碼如下:

#include <iostream.h>
void BubbleSort(int* pData,int Count)
{
int iTemp;
for(int i=1;i<Count;i++) {
for(int j=Count-1;j>=i;j--) {
if(pData[j]<pData[j-1]) {
iTemp = pData[j-1];
pData[j-1] = pData[j];
pData[j] = iTemp;
}
}
}
}
void main() {
int data[] = {10,9,8,7,6,5,4};
BubbleSort(data,7);
for (int i=0;i<7;i++)
cout<<data<<" ";
cout<<"/n";
}

倒序(最糟情況)
第一輪:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,10,8,9->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次交換次數:6次
其他:第一輪:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交換2次)
第二輪:7,8,10,9->7,8,10,9->7,8,10,9(交換0次)
第一輪:7,8,10,9->7,8,9,10(交換1次) 循環次數:6次交換次數:3次 上面我們給出了程序段,
現在我們分析它:這里,影響我們算法性能的主要部分是循環和交換,顯然,次數越多,性能就越差。
從上面的程序我們可以看出循環的次數是固定的,為1+2+...+n-1。寫成公式就是1/2*(n-1)*n。
現在注意,我們給出O方法的定義: 若存在一常量K和起點n0,使當n>=n0時,有f(n)<=K*g(n),則f(n) = O(g(n))。
現在我們來看1/2*(n-1)*n,當K=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。
所以我們程序循環的復雜度為O(n*n)。 再看交換。從程序后面所跟的表可以看到,兩種情況的循環相同,交換不同。
其實交換本身同數據源的有序程度有極大的關系,當數據處于倒序的情況時,交換次數同循環一樣(每次循環判斷都會交換),復雜度為O(n*n)。
當數據為正序,將不會有交換。復雜度為O(0)。亂序時處于中間狀態。正是由于這樣的原因,我們通常都是通過循環次數來對比算法。

2.交換法:

交換法的程序最清晰簡單,每次用當前的元素一一的同其后的元素比較并交換。

復制代碼 代碼如下:

#include <iostream.h>
void ExchangeSort(int* pData,int Count)
{
int iTemp;
for(int i=0;i<Count-1;i++)
{
for(int j=i+1;j<Count;j++)
{
if(pData[j]<pData)
{
iTemp = pData;
pData = pData[j];
pData[j] = iTemp;
}
}
}
}

void main()
{
int data[] = {10,9,8,7,6,5,4};
ExchangeSort(data,7);
for (int i=0;i<7;i++)
cout<<data<<" ";
cout<<"/n";
}

倒序(最糟情況)
第一輪:10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8(交換3次)
第二輪:7,10,9,8->7,9,10,8->7,8,10,9(交換2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:6次

其他:
第一輪:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交換1次)
第二輪:7,10,8,9->7,8,10,9->7,8,10,9(交換1次)
第一輪:7,8,10,9->7,8,9,10(交換1次)
循環次數:6次
交換次數:3次

從運行的表格來看,交換幾乎和冒泡一樣糟。事實確實如此。循環次數和冒泡一樣也是1/2*(n-1)*n,所以算法的復雜度仍然是O(n*n)。由于我們無法給出所有的情況,所以只能直接告訴大家他們在交換上面也是一樣的糟糕(在某些情況下稍好,在某些情況下稍差)。p#副標題#e#

3.選擇法:

現在我們終于可以看到一點希望:選擇法,這種方法提高了一點性能(某些情況下)這種方法類似我們人為的排序習慣:從數據中選擇最小的同第一個值交換,在從省下的部分中選擇最小的與第二個交換,這樣往復下去。

復制代碼 代碼如下:

#include <iostream.h>
void SelectSort(int* pData,int Count)
{
int iTemp;
int iPos;
for(int i=0;i<Count-1;i++)
{
iTemp = pData;
iPos = i;
for(int j=i+1;j<Count;j++)
{
if(pData[j]<iTemp)
{
iTemp = pData[j];
iPos = j;
}
}
pData[iPos] = pData;
pData = iTemp;
}
}

void main()
{
int data[] = {10,9,8,7,6,5,4};
SelectSort(data,7);
for (int i=0;i<7;i++)
cout<<data<<" ";
cout<<"/n";
}

倒序(最糟情況)
第一輪:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交換1次)
第二輪:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交換1次)
第一輪:7,8,9,10->(iTemp=9)7,8,9,10(交換0次)
循環次數:6次
交換次數:2次

其他:
第一輪:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交換1次)
第二輪:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交換1次)
第一輪:7,8,10,9->(iTemp=9)7,8,9,10(交換1次)
循環次數:6次
交換次數:3次
遺憾的是算法需要的循環次數依然是1/2*(n-1)*n。所以算法復雜度為O(n*n)。
我們來看他的交換。由于每次外層循環只產生一次交換(只有一個最小值)。所以f(n)<=n
所以我們有f(n)=O(n)。所以,在數據較亂的時候,可以減少一定的交換次數。4.插入法:
插入法較為復雜,它的基本工作原理是抽出牌,在前面的牌中尋找相應的位置插入,然后繼續下一張

復制代碼 代碼如下:

#include <iostream.h>
void InsertSort(int* pData,int Count)
{
int iTemp;
int iPos;
for(int i=1;i<Count;i++)
{
iTemp = pData;
iPos = i-1;
while((iPos>=0) && (iTemp<pData[iPos]))
{
pData[iPos+1] = pData[iPos];
iPos--;
}
pData[iPos+1] = iTemp;
}
}


void main()
{
int data[] = {10,9,8,7,6,5,4};
InsertSort(data,7);
for (int i=0;i<7;i++)
cout<<data<<" ";
cout<<"/n";
}

倒序(最糟情況)
第一輪:10,9,8,7->9,10,8,7(交換1次)(循環1次)
第二輪:9,10,8,7->8,9,10,7(交換1次)(循環2次)
第一輪:8,9,10,7->7,8,9,10(交換1次)(循環3次)
循環次數:6次
交換次數:3次

其他:
第一輪:8,10,7,9->8,10,7,9(交換0次)(循環1次)
第二輪:8,10,7,9->7,8,10,9(交換1次)(循環2次)
第一輪:7,8,10,9->7,8,9,10(交換1次)(循環1次)
循環次數:4次
交換次數:2次

上面結尾的行為分析事實上造成了一種假象,讓我們認為這種算法是簡單算法中最好的,其實不是,因為其循環次數雖然并不固定,我們仍可以使用O方法。從上面的結果可以看出,循環的次數f(n)<=1/2*n*(n-1)<=1/2*n*n。所以其復雜度仍為O(n*n)(這里說明一下,其實如果不是為了展示這些簡單排序的不同,交換次數仍然可以這樣推導)?,F在看交換,從外觀上看,交換次數是O(n)(推導類似選擇法),但我們每次要進行與內層循環相同次數的‘='操作。正常的一次交換我們需要三次‘='而這里顯然多了一些,所以我們浪費了時間。最終,我個人認為,在簡單排序算法中,選擇法是最好的。插入排序

復制代碼 代碼如下:

#include <iostream>
using namespace std;

void coutstream(int a[],int n){
for(int i=0;i!=n;i++)
cout<<a<<" ";
}

void insertsort(int a[],int n){
int temp;
for(int i=1;i<n;i++)
{
int j=i;
temp=a; //先把a位置的數據存起來
while(j>0&&temp<a[j-1])
{
a[j]=a[j-1];
j--;
}
a[j]=temp;
}
}

int main()
{
int a[5]={1,6,4,8,4};
insertsort(a,5);//插入排序
coutstream(a,5);//
return 0;
}

二、高級排序算法:

高級排序算法中我們將只介紹這一種,同時也是目前我所知道(我看過的資料中)的最快的。它的工作看起來仍然象一個二叉樹。首先我們選擇一個中間值middle程序中我們使用數組中間值,然后把比它小的放在左邊,大的放在右邊(具體的實現是從兩邊找,找到一對后交換)。然后對兩邊分別使用這個過程(最容易的方法――遞歸)。
1.快速排序:

復制代碼 代碼如下:

#include <iostream.h>

void run(int* pData,int left,int right)
{
int i,j;
int middle,iTemp;
i = left;
j = right;
middle = pData[(left+right)/2]; //求中間值
do{
while((pData<middle) && (i<right))//從左掃描大于中值的數
i++;
while((pData[j]>middle) && (j>left))//從右掃描大于中值的數
j--;
if(i<=j)//找到了一對值
{
//交換
iTemp = pData;
pData = pData[j];
pData[j] = iTemp;
i++;
j--;
}
}while(i<=j);//如果兩邊掃描的下標交錯,就停止(完成一次)

//當左邊部分有值(left<j),遞歸左半邊
if(left<j)
run(pData,left,j);
//當右邊部分有值(right>i),遞歸右半邊
if(right>i)
run(pData,i,right);
}

void QuickSort(int* pData,int Count)
{
run(pData,0,Count-1);
}

void main()
{
int data[] = {10,9,8,7,6,5,4};
QuickSort(data,7);
for (int i=0;i<7;i++)
cout<<data<<" ";
cout<<"/n";
}

這里我沒有給出行為的分析,因為這個很簡單,我們直接來分析算法:首先我們考慮最理想的情況
1.數組的大小是2的冪,這樣分下去始終可以被2整除。假設為2的k次方,即k=log2(n)。
2.每次我們選擇的值剛好是中間值,這樣,數組才可以被等分。
第一層遞歸,循環n次,第二層循環2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以算法復雜度為O(log2(n)其他的情況只會比這種情況差,最差的情況是每次選擇到的middle都是最小值或最大值,那么他將變成交換法(由于使用了遞歸,情況更糟)。但是你認為這種情況發生的幾率有多大??呵呵,你完全不必擔心這個問題。實踐證明,大多數的情況,快速排序總是最好的。如果你擔心這個問題,你可以使用堆排序,這是一種穩定的O(log2(n)*n)算法,但是通常情況下速度要慢于快速排序(因為要重組堆)

三、其他排序

1.雙向冒泡:
通常的冒泡是單向的,而這里是雙向的,也就是說還要進行反向的工作。
代碼看起來復雜,仔細理一下就明白了,是一個來回震蕩的方式。
寫這段代碼的作者認為這樣可以在冒泡的基礎上減少一些交換(我不這么認為,也許我錯了)。
反正我認為這是一段有趣的代碼,值得一看。

復制代碼 代碼如下:

#include <iostream.h>
void Bubble2Sort(int* pData,int Count)
{
int iTemp;
int left = 1;
int right =Count -1;
int t;
do
{
//正向的部分
for(int i=right;i>=left;i--)
{
if(pData<pData[i-1])
{
iTemp = pData;
pData = pData[i-1];
pData[i-1] = iTemp;
t = i;
}
}
left = t+1;

//反向的部分
for(i=left;i<right+1;i++)
{
if(pData<pData[i-1])
{
iTemp = pData;
pData = pData[i-1];
pData[i-1] = iTemp;
t = i;
}
}
right = t-1;
}while(left<=right);
}

void main()
{
int data[] = {10,9,8,7,6,5,4};
Bubble2Sort(data,7);
for (int i=0;i<7;i++)
cout<<data<<" ";
cout<<"/n";
}

快速排序

復制代碼 代碼如下:

#include <iostream>
using namespace std;
class QuickSort
{
public:
void quick_sort(int* x,int low,int high)
{
int pivotkey;
if(low <high)
{
pivotkey=partion(x,low,high);
quick_sort(x,low,pivotkey-1);
quick_sort(x,pivotkey+1,high);
}
}
int partion(int* x,int low,int high)
{
int pivotkey;
pivotkey=x[low];
while(low <high)
{
while (low <high&&x[high]>=pivotkey)
--high; //還有while循環只執行這一句
x[low]=x[high];
while (low <high&&x[low] <=pivotkey)
++low; //還有while循環只執行這一句
x[high]=x[low];
}
x[low]=pivotkey;
return low;
}
};
int main()
{
int x[10]={52,49,80,36,14,58,61,97,23,65};
QuickSort qs;
qs.quick_sort(x,0,9);
cout <<"排好序的數字序列為:" <<endl;
for (int i=0;i <10;i++)
{
printf("%d ",x);
}
return 0;
}

2.SHELL排序


這個排序非常復雜,看了程序就知道了。
首先需要一個遞減的步長,這里我們使用的是9、5、3、1(最后的步長必須是1)。
工作原理是首先對相隔9-1個元素的所有內容排序,然后再使用同樣的方法對相隔5-1個元素的排序以次類推。

復制代碼 代碼如下:

#include <iostream.h>
void ShellSort(int* pData,int Count)
{
int step[4];
step[0] = 9;
step[1] = 5;
step[2] = 3;
step[3] = 1;

int iTemp;
int k,s,w;
for(int i=0;i<4;i++)
{
k = step;
s = -k;
for(int j=k;j<Count;j++)
{
iTemp = pData[j];
w = j-k;//求上step個元素的下標
if(s ==0)
{
s = -k;
s++;
pData[s] = iTemp;
}
while((iTemp<pData[w]) && (w>=0) && (w<=Count))
{
pData[w+k] = pData[w];
w = w-k;
}
pData[w+k] = iTemp;
}
}
}

void main()
{
int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};
ShellSort(data,12);
for (int i=0;i<12;i++)
cout<<data<<" ";
cout<<"/n";
}

程序看起來有些頭疼。不過也不是很難,把s==0的塊去掉就輕松多了,這里是避免使用0步長造成程序異常而寫的代碼。這個代碼很值得一看。這個算法的得名是因為其發明者的名字D.L.SHELL。依照參考資料上的說法:“由于復雜的數學原因避免使用2的冪次步長,它能降低算法效率?!绷硗馑惴ǖ膹碗s度為n的1.2次冪。同樣因為非常復雜并“超出本書討論范圍”的原因(我也不知道過程),我們只有結果。冒泡排序性能優化版#include <iostream>

復制代碼 代碼如下:

using namespace std;
void maopao(int *list,int n)
{
int i=n,j,temp;
bool exchange;//當數據已經排好時,退出循環
for(i=0;i<n;i++)
{
exchange=false;
for (j=0;j<n-i-1;j++)
{
if (list[j]>list[j+1])
{
temp=list[j];
list[j]=list[j+1];
list[j+1]=temp;
exchange=true;
}

}
if (!exchange)
{
return;
}
}
}
int main()
{
int a[7]={32,43,22,52,2,10,30};
maopao(a,7);
for(int i=0;i<7;i++)
cout<<a<<" ";
return 0;
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久热在线中文字幕色999舞| 在线观看视频99| 精品国产一区二区三区久久久狼| 精品国产1区2区| 欧美影院在线播放| 中文字幕久热精品视频在线| 日韩精品免费在线观看| 91影视免费在线观看| 亚洲最新中文字幕| 午夜精品一区二区三区在线视| 一区二区三区无码高清视频| 日韩欧美中文在线| 久久91亚洲人成电影网站| 日韩电影免费观看在线| 国产综合久久久久久| 精品小视频在线| 亚洲人成电影在线| 日韩av黄色在线观看| 欧美电影免费观看网站| 国模私拍一区二区三区| 日韩av综合中文字幕| 国产精品女人网站| 精品久久久久久亚洲国产300| 欧美另类精品xxxx孕妇| 精品视频9999| 日韩中文字幕在线视频播放| 日韩高清中文字幕| 国产精品男人的天堂| 国产精品成久久久久三级| 国产精品99蜜臀久久不卡二区| 国产精品av电影| 精品亚洲一区二区三区在线观看| 97视频在线观看免费| 色综合五月天导航| 久久频这里精品99香蕉| 精品亚洲国产视频| 日本久久久久久久久久久| 亚洲色图综合网| 欧美影院成年免费版| 久久综合色影院| 欧美寡妇偷汉性猛交| 视频一区视频二区国产精品| 亚洲欧美成人一区二区在线电影| 国产精品网站视频| 日韩视频免费大全中文字幕| 久久国产精品久久久久| 国产成人久久久精品一区| 亚洲www在线观看| 亚洲老司机av| 久久精品国亚洲| 亚洲一二在线观看| 国产在线观看精品| 中文字幕亚洲国产| 欧美性猛交xxxx富婆| 91精品国产亚洲| 国产精品久久婷婷六月丁香| 久久国产精品免费视频| 国产一区二区成人| 国产日韩欧美夫妻视频在线观看| 亚洲精品永久免费精品| 亚洲欧美日韩一区二区三区在线| 欧美一性一乱一交一视频| 久久国产视频网站| 欧美日韩亚洲激情| 九九热精品视频在线播放| 亚洲精品综合精品自拍| 欧美成aaa人片免费看| 5252色成人免费视频| 久久久国产在线视频| 欧美色道久久88综合亚洲精品| 91在线高清视频| 国产欧美日韩中文字幕在线| 91国产中文字幕| 97色在线播放视频| 亚洲高清一区二| 色综合伊人色综合网| 亚洲第一在线视频| 亚洲天堂av女优| 最近2019中文字幕一页二页| 欧美老少做受xxxx高潮| 美女久久久久久久久久久| 国产精品欧美久久久| 欧美精品videos| 亚洲福利视频免费观看| 成人黄色在线播放| 国产亚洲精品一区二区| 日韩福利伦理影院免费| 欧美成人精品在线视频| 欧美黄网免费在线观看| 久久久噜噜噜久久久| 一级做a爰片久久毛片美女图片| 最近2019年日本中文免费字幕| 操人视频在线观看欧美| 国产精品久久久久久久久影视| 久久综合免费视频影院| 少妇高潮久久77777| 久久久精品一区二区| 伊人一区二区三区久久精品| 97在线精品视频| 精品成人69xx.xyz| 97成人精品视频在线观看| 91禁国产网站| 亚洲一区av在线播放| 91精品国产网站| 亚洲福利在线看| 久久久精品久久久| 久久久午夜视频| 91丝袜美腿美女视频网站| 欧美丝袜一区二区| 欧美性videos高清精品| 精品国产乱码久久久久久婷婷| 国产中文欧美精品| 91久久中文字幕| 精品视频9999| 欧美日韩电影在线观看| 午夜精品美女自拍福到在线| 久久精品99无色码中文字幕| 久久久最新网址| 日韩不卡在线观看| 欧美性xxxxx极品娇小| 国产精品普通话| 久久精品成人欧美大片| 国产精品成人av在线| 欧美精品aaa| 欧美在线观看一区二区三区| 国产成人精品免高潮费视频| 国产精品自拍网| 欧美视频免费在线观看| 亚洲视频国产视频| 亚洲精品中文字幕av| 欧美三级欧美成人高清www| 国内精品视频久久| 91高潮在线观看| 91色在线观看| 国产精品福利片| 久久视频精品在线| 国产精品海角社区在线观看| 国产精品日韩在线观看| 久久久久久国产免费| 色婷婷久久一区二区| 欧美日韩国产中文字幕| 亚洲最大的av网站| 欧美视频在线观看免费| 欧美成人小视频| 日韩中文字幕亚洲| 欧美日韩在线视频观看| 欧美日韩国产成人在线| 欧美激情久久久久久| 在线播放国产一区二区三区| 国产91精品视频在线观看| 日韩中文理论片| 国产精品久久97| 亚洲第一二三四五区| 在线观看精品自拍私拍| 最新国产精品亚洲| 国产精品十八以下禁看| 色小说视频一区| 欧美在线激情网| 91成品人片a无限观看| 精品magnet| 成人免费视频xnxx.com| 久久久久久亚洲精品| 亚洲精品福利视频| 一区二区亚洲欧洲国产日韩|