您的位置:首页 > 其它

排序算法的比较---插入、选择、快排

2014-03-30 15:28 225 查看
实验代码:

#include<iostream>

#include<cstdlib>

#include<time.h>

#define N 100000

using namespace std;

class Array

{

public: Array(); //构造函数

void Sort_decent(); //辅助构造函数产生非递增序列

void Sort_one(); //排序方案一:插入排序

void Sort_two(); //排序方案二:选则排序

void Sort_three_SampleOne(int *Sample,int start,int end); //排序方案三:快速排序

void Sort_three_SampleOne_time(); //为乱序数组快排计时

void Sort_three_SampleTwo_time(); //为顺序数组快排计时

private: void Show_result(int *p); //如果需要可以使用来显示排序结果:

//因为测试数据数量较多,所以略去这一步

//小规模测试可以考虑使用(后面给出了其代码实现)

int sarray
; //随机数组

int darray
; //非递增数组

};

Array::Array()

{

for(int i=0;i<N;i++) //产生随机数组

{

srand(i);

sarray[i] = darray[i] = rand()%N;

}

Sort_decent(); //将数组darray非递增排序

}

void Array::Sort_decent()

{

int temp;

for(int i=0;i<N-1;i++)

{

for(int j=i;j<N;j++)

if(darray[i]<darray[j])

{

temp = darray[i];

darray[i] = darray[j];

darray[j] = temp;

}

}

}

void Array::Sort_one() //排序方案一:插入排序

{ int Sample_one
;

int Sample_two
; //样本数组:sarray与darray的两个样本,下同

int i,j,k,l;

for( i=0 ;i<N;i++)

{

Sample_one[i] = sarray[i];

Sample_two[i] = darray[i];

}

clock_t start1 = clock(); //记录排序起始时间,下同

for( j=1;j<N;j++ ) //对乱序数组排序

{

k = Sample_one[j];

l = j-1;

while((k>=0)&&(Sample_one[l]>k))

{

Sample_one[l+1] = Sample_one[l];

l--;

}

Sample_one[l+1] = k;

}

clock_t end1=clock(); //记录排序终了时间,下同

// Show_result(Sample_one);

cout<<"乱序数组插入排序用时: "<<end1-start1<<" ms"<<endl;

// Show_result(Sample_two);

clock_t start2=clock();

for( j=1;j<N;j++ ) //对顺序数组排序

{

k = Sample_two[j];

l = j-1;

while((k>=0)&&(Sample_two[l]>k))

{

Sample_two[l+1] = Sample_two[l];

l--;

}

Sample_two[l+1] = k;

}

clock_t end2=clock();

// Show_result(Sample_two);

cout<<"顺序数组插入排序用时: "<<end2-start2<<" ms"<<endl;

}

void Array::Sort_two() //排序方案二:选择排序

{

int Sample_one
;

int Sample_two
;

int i;

for( i=0 ;i<N;i++)

{

Sample_one[i] = sarray[i];

Sample_two[i] = darray[i];

}

clock_t start1 = clock();

for ( i = 0; i < N; i++)

{

int min = Sample_one[i], min_index = i;

for (int j = i; j < N; j++)

{

if (Sample_one[j] < min)

{

min = Sample_one[j];

min_index = j;

}

}

if (min_index != i)

{

int temp = Sample_one[i];

Sample_one[i] = Sample_one[min_index];

Sample_one[min_index] = temp;

}

}

clock_t end1=clock();

// Show_result(Sample_one);

cout << "乱序数组选择排序用时: "<<end1-start1<<" ms"<<endl;

clock_t start2 = clock();

for( i=0; i < N; i++)

{

int min = Sample_two[i], min_index = i;

for (int j = i; j < N; j++)

{

if (Sample_two[j] < min)

{

min = Sample_two[j];

min_index = j;

}

}

if (min_index != i)

{

int temp = Sample_two[i];

Sample_two[i] = Sample_two[min_index];

Sample_two[min_index] = temp;

}

}

clock_t end2=clock();

// Show_result(Sample_two);

cout<<"顺序数组选择排序用时: "<<end2-start2<<" ms"<<endl;

}

void Array::Sort_three_SampleOne(int *Sample_one,int start,int end) //排序方案三:快速排序

{

int i,j,std_data;

if(start < end)

{ //第一趟排序

i = start;

j = end;

std_data = Sample_one[start];

while(i<j)

{

while(Sample_one[j]>=std_data&&i<j)

{

j--;

}

if(i<j) Sample_one[i++] = Sample_one[j];

while(Sample_one[i]<=std_data&&i<j)

{

i++;

}

if(i<j) Sample_one[j--] = Sample_one[i];

}

Sample_one[i] = std_data;

Sort_three_SampleOne(Sample_one,start,i-1);

Sort_three_SampleOne(Sample_one,i+1,end);

}

}

void Array::Sort_three_SampleOne_time() //记录乱序数组排序时间

{

int Sample_one
;

for(int i=0 ;i<N;i++)

{

Sample_one[i] = sarray[i];

}

clock_t start1 = clock();

Sort_three_SampleOne(Sample_one,0,N-1);

clock_t end1 = clock();

cout<<"乱序数组快速排序用时: "<<end1-start1<<" ms"<<endl;

}

void Array::Sort_three_SampleTwo_time() //记录顺序数组排序时间

{

int Sample_two
;

for(int i=0 ;i<N;i++)

{

Sample_two[i] = darray[i];

}

clock_t start2 = clock();

Sort_three_SampleOne(Sample_two,0,N-1);

clock_t end2 = clock();

cout<<"顺序数组快速排序用时: "<<end2-start2<<" ms"<<endl;

}

void Array::Show_result(int *p)

{

for(int i=0;i<N;i++)

cout<<p[i]<<"\t";

}

int main(void)

{

Array array;

array.Sort_one();

array.Sort_two();

array.Sort_three_SampleOne_time();

array.Sort_three_SampleTwo_time();

return 0;

}

代码在Vs2012上编译运行通过,运行时可自行修改N的值从而改变排序规模

总结:

(1)算法部分:

这个程序的编写是用面向对象的思想进行的,Array类有Sort_one()

Sort_two()、Sort_three()三个行为即插入、选择、快速排序以及两个数组成员sarray,darray.从数据结构方面的知识我们知道插入排序的时间复杂度为O(n^2),从实验结果可以看出它并不适合数据量很大的排序,而选择排序与插入排序的时间复杂度同为O(n^2)所以也不适合大量数据的排序,但是从截图可以看出在乱序数组排序时,插入排序较选择排序更具有优势,快速排序对乱序数组的排序具有十分明显的优势,其时间复杂度为O(nLogn),从实验结果来看也的确如此,随着数据量的增大快排很显然是最好的选择,但是也该注意到快排对于顺序数组的排序时间复杂度的数量级也是O(n^2),所以具体使用哪种排序方式还得具体情况具体分析。

(2)类的设计部分:

之前有考虑将排序前后的结果输出,但是实验要求是测试大规模数据的排序,所以数组的输出会使得结果显得十分累赘而没有突出重点,但还是给出了其实现,所以Array类的Show_result()成员,仅供使用者依据需要自行使用(最好用于小规模的数据输出)。另外的不足之处在于,Sort_one()、Sort_two()、Sort_three()三个成员都要对sarray与darray两个私有成员中的数据进行处理,可谓“僧多粥少”,所以在设计时每个方法都定义了两个局部变量Sample_one与Sample_two用于复制sarray与darray,但是这样无疑是中糟糕的方案,其实自己的想法是每个成员处理了数组之后能够将其复原,这样可以节省内存分配所用时间,但是知识与技术有限,没能这样实现,所以以后还得更加努力学习C++面向对象的编程思想。

(3)错误经验分析:

在程序结果正确输出前,犯了一个十分严重的错误,就是未意识到快速排序的递归性,而将时间测量也放在了快排函数的实现中,而结果输出出错。就这点我深刻意识到了递归函数的功能一定要是十分单一的,只能解决一个问题,不断将其规模变小,这个过程中不能添加其它的过程,否则其它也会参与递归,这是应该十分警惕的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐