實驗內容
分別針對隨機產生的三組整數序列(規模為1000個數、10000個數、100000個數)進行排序,排序演算法使用以下五種經典的方法,分別是:冒泡排序演算法,選擇排序演算法,插入排序演算法,歸併排序演算法和快速排序演算法。
實驗目的
• 回顧並熟悉常用的排序演算法。
• 通過實驗體會演算法設計對問題求解效率所產生的深刻影響。
演算法設計的基本思路
選擇排序
在要排序的一組數中,選出最小的一個數與第一個位置的數交換;然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈 到倒數第二個數和最後一個數比較為止。
直接插入排序
在要排序的一組數中,假設前面(n-1) [n>=2] 個數已經是排好順序的,現在要把第n個數插到前面的有序數中,使得這n個數也是排好順序的。如此反覆迴圈,直到全部排好順序。
冒泡排序
在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。
歸併排序演算法
合并排序(MERGE SORT)是又一類不同的排序方法,合并的含義就是將兩個或兩個以上的有序資料序列合并成一個新的有序資料序列,因此它又叫歸併演算法。它的基本思想就是假設數組A有N個元素,那麼可以看成數組A是又N個有序的子序列組成,每個子序列的長度為1,然後再兩兩合并,得到了一個 N/2 個長度為2或1的有序子序列,再兩兩合并,如此重複,直到得到一個長度為N的有序資料序列為止,這種排序方法稱為2—路合并排序。
快速排序
快速排序是對冒泡排序的一種本質改進。它的基本思想是通過一趟掃描後,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只減少1。快速排序通過一趟掃描,就能確保某個數(以它為基準點吧) 的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理它左右兩邊的數,直到基準點的左右只有一個元素為止。
程式清單
#include<stdlib.h>
#include<stdio.h>
#include<ctime>
#include<iostream>
using namespace std;
void Swap(int &X,int &Y) //兩個數交換
{int temp;
temp=X;
X=Y;
Y=temp;
}
/**************************************起泡排序法****************************/
void BubbleSort(int R[],int Length)
{
int i,j,t;
i=Length-1;
while(i>0)
{t=0;
for(j=0;j<i;j++)
if(R[j+1]<R[j])
{Swap(R[j],R[j+1]);
t=j;
}
i=t;
}
}
/*******************************直接選擇排序法********************************/
void SelectionSort(int R[],int Length)
{int min,i,j;
for(i=0;i<Length;i++)
{min=i;
for(j=i+1;j<Length;j++)
if(R[j]<R[min])min=j;
Swap(R[i],R[min]);
}
}
/********************************直接插入排序法*******************************/
void InsertionSort(int R[],int Length)
{int i,j,k;
for(i=1;i<Length;i++)
{
if(R[i]<R[i-1])
{k=R[i];
j=i-1;
do{
R[j+1]=R[j];
j--;
}while(j>=0&&k<R[j]);
R[j+1]=k;
}
}
}
/********************************歸併排序法**********************************/
void Merge(int L1[],int L2[],const int left,const int mid,const int right)
//兩個子序列合并成一個組列
{
for(int k=left;k<=right;k++)
L2[k]=L1[k];
int s1=left,s2=mid+1,t=left; // s1,s2是檢測指標,t是存放指標
while(s1<=mid&&s2<=right) //兩個數組都未檢測完,兩兩比較
if(L2[s1]<=L2[s2])L1[t++]=L2[s1++];
else L1[t++]=L2[s2++];
while(s1<=mid)L1[t++]=L2[s1++]; //若第一個數組為檢測完,複製
while(s2<=right)L1[t++]=L2[s2++]; //若第二個數組為檢測完,複製
}
void MergeSort(int L[],int L2[],int left,int right)
{
if(left>=right)return;
int mid=(left+right)/2; //從中間劃分為兩個子序列
MergeSort(L,L2,left,mid); //對左側子序列進行遞迴排序
MergeSort(L,L2,mid+1,right); //對右側子序列進行遞迴排序
Merge(L,L2,left,mid,right); //合并
}
/*******************************快速排序法************************************/
int Partition(int L[],int low,int high)//將序列劃分成兩個子序列
{ int temp;
L[0]=L[low]; //基準元素
temp=L[low];
while(low<high) //檢測整個序列,進行劃分
{ while(low<high&&L[high]>=temp)--high;
L[low]=L[high]; //小於基準元素,交換到左邊
while(low<high&&L[low]<=temp)++low;
L[high]=L[low]; //大於基準元素放右邊
}
L[low]=L[0];
return low; //返回基準元素
}
void QuickSort(int R[],int left,int right) //快速排序
{ int pivotloc;
if(left<right)
{pivotloc=Partition(R,left,right);//找中間值劃分
QuickSort(R,left,pivotloc-1);//遞迴左邊
QuickSort(R,pivotloc+1,right);//遞迴右邊
}
}
void Exchange(int B[],int C[],int Length)//兩個數組值交換
{ int k;
for(k=0;k<Length;k++)
B[k]=C[k];
}
void Print(int R[],int length)//輸出序列
{for(int i=0;i<length;i++)
cout<<R[i]<<" ";
cout<<endl;
}
int main()
{ int i,j;
int A[100000]={0};int N[100000]={0};
int R[]={1000,10000,100000};
double start,finish,duration;
srand(time(0));
for(j=0;j<3;j++)
{ cout<<endl<<R[j]<<"個數五種排序用時情況"<<endl;
for(i=0;i<R[j];i++)
{ A[i]=rand()%R[j];
N[i]=A[i];
}
//Print(A,R[j]);
start=clock();
BubbleSort(A,R[j]);
finish=clock();
duration=(finish-start)/CLOCKS_PER_SEC*1000;
cout<<" BubbleSort need the time:"<<duration<<endl;
//Print(A,R[j]);
Exchange(A,N,R[j]);//保證排序用同一數組
start=clock();
SelectionSort(A,R[j]);
finish=clock();
duration=(finish-start)/CLOCKS_PER_SEC*1000;
cout<<" SelectionSort need the time:"<<duration<<endl;
//Print(A,R[j]);
Exchange(A,N,R[j]);
start=clock();
InsertionSort( A,R[j]);
finish=clock();
duration=(finish-start)/CLOCKS_PER_SEC*1000;
cout<<" InsertionSort need the time:"<<duration<<endl;
//Print(A,R[j]);
Exchange(A,N,R[j]);
start=clock();
MergeSort(A,N,0,R[j]-1);
finish=clock();
duration=(finish-start)/CLOCKS_PER_SEC*1000;
cout<<" MergeSort need the time:"<<duration<<endl;
//Print(A,R[j]);
Exchange(A,N,R[j]);
start=clock();
QuickSort(A,0,R[j]-1);
finish=clock();
duration=(finish-start)/CLOCKS_PER_SEC*1000;
cout<<" QuickSort need the time:"<<duration<<endl;
//Print(A,R[j]);
}
return 0;
}
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/zshrong/archive/2009/10/26/4730468.aspx