为什么我的合并排序代码比插入排序慢

时间:2013-10-12 01:18:53

标签: c++ algorithm sorting mergesort insertion-sort

我一直在尝试进行合并排序和插入排序,并比较两者的时间结果。 从数组输入大小10到10000合并排序比插入排序慢

这是插入排序的代码

vector<int> insertion_sort(vector<int> vec)
{
    for(int i = 1 ; i <vec.size();i++)
    {
        int j = i-1;
        while(j>=0 && vec[j+1]<vec[j] )
        {
            int x = vec[j+1];
            vec[j+1] = vec[j];
            vec[j--] = x;
        }
    }
    return vec;
}

这是合并排序代码

vector<int> merge(vector<int> left,vector<int> right)
{
    int i = 0;
    int j = 0;
    vector<int> ret(left.size()+right.size());
    int it = 0;
    for(; i <left.size() && j<right.size();)
    {
        if(left[i]<right[j])
            ret[it++]=(left[i++]);
        else if(right[j]<left[i])
            ret[it++]=(right[j++]);
        else ret[it++]=(left[i++]),ret[it++]=(right[j++]);
    }
    for(;i<left.size();)
        ret[it++]=(left[i++]);
    for(;j<right.size();)
        ret[it++]=(right[j++]);
    return ret;
}
vector<int> merge_sort(vector<int> A,int start,int end)
{
    if(start >= end) 
    {
        vector<int> v(1);
        v[0]=(A[start]);
        return v;
    }
    int mid = (start+end )/ 2;
    vector<int> left = merge_sort(A,start,mid);
    vector<int> right = merge_sort(A,mid+1,end);
    return merge(left,right);
}

最后这就是我调用所有这些并计算时间的方法

int main()
{
    vector<int> rand_vec;

    srand(time(0));
    for(int i = 0 ; i <SIZE;i++)
    {
        rand_vec.push_back(rand()%SIZE);
    }
    int t = clock();
    vector<int> merge_sorted = merge_sort(rand_vec,0,rand_vec.size()-1);
    puts("");
    printf("merge sort time = %d\n",clock() - t );


    t = clock();
    vector<int> insertion_sorted = insertion_sort(rand_vec);
    puts("");
    printf("insertion sort time = %d\n",clock() - t );
    return 0;
}

我想知道我是否在该代码中做错了什么来使合并排序的时间超过插入排序时使用的时间。

感谢。

4 个答案:

答案 0 :(得分:3)

通过引用而不是按值传递向量会产生巨大的差异。在我的机器上,SIZE = 50000,使用-O3编译,之前:

merge sort time = 5730000

insertion sort time = 1470000

后:

merge sort time = 10000

insertion sort time = 1470000

我只更改了两行:

vector<int> merge(const vector<int> &left,const vector<int> &right)
vector<int> merge_sort(const vector<int> &A,int start,int end) 

答案 1 :(得分:1)

总结到目前为止提供的答案:
- 使用引用(或指针)来避免复制向量:
- 在使用数千reserve之前,在事先知道尺寸时使用push_back(这样,无论何时超出容量,您都不需要动态重新分配) - 您可以执行const vector<int>& merge_sorted = ...以避免在返回矢量时复制

答案 2 :(得分:0)

除了关于引用的mrip答案外,请记住:

“插入排序是排序非常小的数组的最快算法之一,甚至比快速排序更快。最好的情况输入是已经排序的数组。在这种情况下,插入排序具有线性运行时间。最简单的最坏情况input是一个按相反顺序排序的数组。“

答案 3 :(得分:0)

合并排序不一定比插入排序慢。 通过插入排序的时间来排序&#39; n&#39;项目与n平方(n n)成比例,而合并排序所花费的时间与n base 2的n次对数成比例(n lgn) 因此,在某些代码中插入排序比合并排序更快,而在其他代码中合并排序