【问题标题】:I can't seem to figure out why my merge sort is so slow我似乎无法弄清楚为什么我的合并排序这么慢
【发布时间】:2017-10-08 23:40:22
【问题描述】:

我一直在查看这里的所有线程,但似乎找不到有效的解决方案。排序有效,但与应有的速度相比,它的速度非常慢。这是代码(我正在处理头文件):

#pragma once
#ifndef DataGen_h
#define DataGen_h

#include "RandomSupport.h"

void merge(long list[], long start, long mid, long end) { 
    long i = start; 
    long j = mid + 1; 
    while (j <= end && i <= mid) { 
        if (list[i] < list[j]) {
            i++; 
        } 
        else { 
            long temp = list[j]; 
            for (long k = j; k > i; k--) {
            list[k] = list[k - 1]; 
            }
            list[i] = temp; 
            mid++; 
            i++; 
            j++; 
        } 
    } 
}

void merge_sort(long list[], long startIndex, long endIndex)
{
    if (startIndex >= endIndex){
        return;
    }

    long midIndex = (startIndex + endIndex) / 2;
    merge_sort(list , startIndex, midIndex);
    merge_sort(list, midIndex + 1, endIndex);
    merge(list, startIndex, midIndex, endIndex);
}




void efficientRandomSortedList(long temp[], long s) {
    // Get a new random device
    randomizer device = new_randomizer();
    // Get a uniform distribution from 1 to 1000
    uniform_distribution range = new_distribution(1, 45000);

    for (long i = 0; i < s; i++) {
        // At every cell of the array, insert a randomly selected number
        // from distribution defined above
        temp[i] = sample(range, device);
    }

    // Now sort the array using insertion_sort

    merge_sort(temp, 0, s - 1);
}


#endif /* DataGen_h */

这是针对班级的,所以很遗憾我无法更改正在使用的数据类型。对我的格式的任何帮助或一般批评都会有所帮助。

【问题讨论】:

  • 您能提供一些性能数据吗?请记住,归并排序的平均性能为 O(N*lgN),因此如果您的代码扩展到此,那么就不会出错。
  • 您的merge 是二次方的,因为您每次需要插入时都会移动O(n) 元素。这有点破坏了整个观点。
  • 我已经浏览了这里的所有主题,似乎找不到有效的解决方案。 -- 你搜索的不够仔细。你看到this thread了吗?
  • 合并排序最适合链表,尝试pivot-sort,例如连续数据
  • @sp2danny 枢轴排序是否适用于较大的数据集?例如多达 1500 万个随机数字?

标签: c++ sorting merge


【解决方案1】:

如果你打算这样做merge,你还不如做选择排序;合并步骤都是二次的,你仍然在做它们的对数。

就地合并排序很棘手(而且不如合并排序快)。您应该只合并到一个临时向量中,然后复制回原始向量。或者通过在递归时交替两个向量来避免复制。

【讨论】:

  • 就地归并排序很棘手,但如果不需要稳定性,它仍然可以具有 O(n log(n)) 的时间复杂度,尽管比普通归并排序慢。 this answer 中显示的混合就地合并/插入排序的示例 java 代码。
  • @rcgldr:这很漂亮。
【解决方案2】:

冒泡排序是一种 O(n²) 算法,速度很慢。合并排序是 O(nlogn),速度很快。

要了解这些算法的速度,请参阅https://www.toptal.com/developers/sorting-algorithms

【讨论】:

  • 我正在使用合并排序
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-04
  • 2017-05-30
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 2020-11-14
  • 2021-04-26
相关资源
最近更新 更多