【问题标题】:Why quickSort is slower then bubblesort?为什么快速排序比冒泡排序慢?
【发布时间】:2017-03-18 13:00:47
【问题描述】:

所以我在我的大学里有一门课,我们做各种各样的事情,现在我们进行递归排序,也就是快速排序。好吧,你们都知道它的作用,将数组分成两部分,依此类推,直到它以 1 个元素结尾,然后对它们进行排序。

所以我们讨论了哪一个会更快以及为什么这被称为快速排序,最终快速排序的复杂度是 n.log2(n),而例如冒泡排序是 n^2。好的,所以我在 c# 中编写了 bouth 代码,并使用 c# i calcualte hte ms 的秒表来执行 bouth alogirithyms ,其中我生成 -65000,65000 和长度为 50 000 个元素的数组之间的随机数。

因此,bubblesort 在第一次 23 秒第二次 29 时进行了排序(因为它们是随机的 ..),即使我创建了一个包含 50k 个元素且第一个元素为 n-i 的数组。 Aka 它需要对所有内容进行排序,如果我从 i 开始创建一个数组,它会执行 27 秒(所以关闭随机数),它确实需要 17 秒来排序。

所以我运行了 quickSort ,已经过了 5 分钟,仍然没有结果......如果我用 arra[i] = i; 运行它或 n-i;它给了我stackoverflow异常。

qSort 更快的唯一地方是当有一个包含 100 或 200 之类的元素的数组并且它们已经排序(又名 array[i]=i)并且它更快,例如 0.1-0.2 秒。冒泡排序可以对非常大的数组进行排序,而 qSort 给了我stackoverflow。

回到复杂性,50 000 个元素的 qSort = 780482 而bublesort = 2 500 000 000 清明如晴天qSort需要什么?快 99.99%。但不是吗?为什么我真的对此很好奇,因为我的 Lector 说过 qSort 快得多。但经过所有类型的测试后,与冒泡排序相比,它似乎(稍微)快一些,并且它仅适用于元素不多的数组。(10k 随机元素 qSort 17 秒,而气泡排序 7)。

我的电脑是 i7 4 核,每个 2.6 ghz,我有 16 GB RAM DDR4。

如果有人把事情弄清楚,我会很高兴,因为我的讲师似乎给了我一个虚假的信息。

编辑两个代码: qsort..................................

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuickSort
{
class QuickSort
{
    static public int Partition(int[] numbers, int left, int right)
    {
        int pivot = numbers[left];
        while (true)
        {
            while (numbers[left] < pivot)
                left++;

            while (numbers[right] > pivot)
                right--;

            if (left < right)
            {
                int temp = numbers[right];
                numbers[right] = numbers[left];
                numbers[left] = temp;
            }
            else
            {
                return right;
            }
        }
    }

    static public void SortQuick(int[] arr, int left, int right)
    {
        // For Recusrion  
        if (left < right)
        {
            int pivot = Partition(arr, left, right);

            if (pivot > 1)
                SortQuick(arr, left, pivot - 1);

            if (pivot + 1 < right)
                SortQuick(arr, pivot + 1, right);
        }
    }

    static void Main(string[] args)
    {
        var watch = System.Diagnostics.Stopwatch.StartNew();
        Random rnd = new Random();

        int max = Convert.ToInt32(Console.ReadLine());

        int[] numbers = new int[max];

        for (int i = 0; i < max; i++)
        {

            numbers[i] = rnd.Next(-65000, 65000);
        }


        // the code that you want to measure comes here






        SortQuick(numbers, 0, max - 1);

        for (int i = 0; i < max; i++)
            Console.WriteLine(numbers[i]);
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine(elapsedMs);
        Console.ReadLine();
    }
}
}

冒泡排序..................................

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace bublesort
{
class Program
{
    static void Main(string[] args)
    {
        var watch = System.Diagnostics.Stopwatch.StartNew();
        // the code that you want to measure comes here

        int n = int.Parse(Console.ReadLine());
        int[] arr = new int[n];
        Random rnd = new Random();
        int temp = 0;
        for (int i = 0; i < n; i++)
        {

            arr[i] = rnd.Next(-65000,65000);
        }
        for (int write = 0; write < arr.Length; write++)
        {
            for (int sort = 0; sort < arr.Length - 1; sort++)
            {
                if (arr[sort] > arr[sort + 1])
                {
                    temp = arr[sort + 1];
                    arr[sort + 1] = arr[sort];
                    arr[sort] = temp;
                }
            }
        }

        for (int i = 0; i < arr.Length; i++)
            Console.WriteLine(arr[i]);
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
        Console.WriteLine(elapsedMs);
    }
}
}

【问题讨论】:

  • 没有看到您的代码就无法判断,但很可能您的快速排序没有得到有效实施。 stackoverflow.com/questions/33452614/….
  • 添加到@BrendanFrick 的评论中,以真正的递归 (f(x):=f(x')) 实现在 (CPU) 时间和 (RAM) 空间方面都非常昂贵。由于递归是语法糖,每个递归也可以在没有递归的情况下实现。
  • 我已经发布了both代码,请检查qSort是否有问题。我真的希望我在代码中做错了什么。
  • 交换两个项目后,您需要移动partition 中的leftright 索引。
  • HHAHAHA 所以菜鸟错误。 THx 很多 :) 现在一切都像是假设 50 000 个元素需要 8 秒,而 bublesort 29。:) THX!

标签: arrays sorting compare quicksort bubble-sort


【解决方案1】:

如果您的数组中有重复项,则会发生两个 while 循环以 array [left] = array [right] = pivot 结尾。交换什么也不做,因为你不增加左减右,你的快速排序将永远卡住。

尝试使用长度为 2 和两个相等元素的数组。它会立即挂起。

此外,通过选择数组 [left] 作为基准,一旦修复了该错误,您就可以保证排序数组的最坏情况(二次)行为。

【讨论】:

    【解决方案2】:
     static public void Quicksort(int[] numbers, int left, int right)
        {
            int i = left, j = right;
            int pivot = numbers[(left+right)/2];
    
            while (i <= j)
            {
                while (numbers[i] < pivot)
                {
                    i++;
                }
    
                while (numbers[j] > pivot)
                {
                    j--;
                }
    
                if (i <=j)
                {
                    // Swap
                    int tmp = numbers[i];
                   numbers[i] = numbers[j];
                   numbers[j] = tmp;
    
                    i++;
                    j--;
                }
    
            }
    
            // Recursive calls
            if (left < j)
            {
                Quicksort(numbers, left, j);
            }
    
            if (i < right)
            {
                Quicksort(numbers, i, right);
            }
        }
    

    是的问题解决了指导的问题,当我将枢轴作为中间元素时,我现在在区间 [-65000 到 65000] 中对 100 000 个随机元素进行排序 8 秒。而冒泡排序需要 71 秒。或者 Q 排序比 bublesort 快 90% ;)。

    【讨论】:

      猜你喜欢
      • 2018-03-28
      • 2011-11-30
      • 2022-01-15
      • 2019-02-26
      • 2021-11-24
      • 2017-01-30
      • 2015-09-12
      • 2011-06-22
      • 1970-01-01
      相关资源
      最近更新 更多