- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
归并排序的最坏情况复杂度为 O(logN),而快速排序的最坏情况复杂度为 O(N^2),因此理论上归并排序的性能应该优于快速排序。但我听说由于一些复制开销,大多数情况下快速排序优于合并排序。 See the reference .
然后我决定实现和测试,下面是我的完整 C 源代码,
#include <stdio.h>
#include <time.h>
#define SZ 10000000
#define MOD 10000007
#define i64 long long int
i64 nums[SZ];
i64 L[SZ], R[SZ];
i64 seed = 0xff;
i64 srand(){
seed = (seed + 17 * seed) % MOD;
return seed;
}
void make(){
for (register int i = 0; i < SZ; i++)
nums[i] = srand() % MOD;
}
void swap(i64 *a, i64 *b){
i64 t = *a;
*a = *b;
*b = t;
}
int pivote(int s, int e){
//int p = s + srand() % (e - s + 1);
int p = s + (e - s) / 2;
//int p = s;
//int p = e;
i64 v = nums[p];
int c = s;
swap(nums + p, nums + e);
for (register int i = s; i < e; i++){
if (nums[i] < v){
swap(nums + i, nums + c);
c++;
}
}
swap(nums + c, nums + e);
return c;
}
void qsort(int s, int e){
if (s < e){
int p = pivote(s, e);
qsort(s, p - 1);
qsort(p + 1, e);
}
}
void merge(i64 arr[], int l, int m, int r){
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2)
{
if (L[i] <= R[j])
{
arr[k] = L[i];
i++;
}
else
{
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1)
{
arr[k] = L[i];
i++;
k++;
}
while (j < n2)
{
arr[k] = R[j];
j++;
k++;
}
}
void mergeSort(i64 arr[], int l, int r){
if (l < r){
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
void testQsort(){
double s, e;
make();
s = clock();
qsort(0, SZ - 1);
e = clock();
printf("qsort random: %Lf ms\n", (e - s) / 1);
s = clock();
qsort(0, SZ - 1);
e = clock();
printf("qsort sorted: %Lf ms\n", (e - s) / 1);
}
void testMsort(){
double s, e;
make();
s = clock();
mergeSort(nums, 0, SZ - 1);
e = clock();
printf("msort random: %Lf ms\n", (e - s) / 1);
s = clock();
mergeSort(nums, 0, SZ - 1);
e = clock();
printf("msort sorted: %Lf ms\n", (e - s) / 1);
}
int main(){
testMsort();
testQsort();
return 0;
}
msort random: 4596.000000 ms
msort sorted: 3354.000000 ms
qsort random: 7637.000000 ms
qsort sorted: 5074.000000 ms
我用过四个版本的快速排序,
似乎没有一个版本的快速排序优于归并排序。谁能说出为什么提到快速排序优于归并排序?
我的快速排序实现有什么问题吗?
根据下面提到的@rcgldr 的回答,我测试了以下版本的快速排序,它最终优于任何版本的合并排序。
void qsort3(int s, int e){
if (s < e){
i64 p = nums[(s + e) / 2];
int i = s - 1;
int j = e + 1;
while (true){
while (nums[++i] < p);
while (nums[--j] > p);
if (i >= j) break;
swap(nums + i, nums + j);
}
qsort3(s, j);
qsort3(j + 1, e);
}
}
最佳答案
问题的快速排序示例基于 Lomuto 分区方案,它比 Hoare 分区方案慢。链接到 Hoare 分区方案的示例:
QuickSort with middle elemenet as pivot
合并排序的例子是不断地创建子数组和复制数据。一种更有效的方法是对数组进行一次分配,然后根据自上而下归并排序的递归级别或自下而上归并排序的遍数更改归并方向。链接到显示自下而上和自上而下合并排序的 Java 源代码。这可以很容易地转换为 c:
'MergeSort Algorithm' - What's the better implementation in JAVA?
至于相对性能,一个简单的快速排序(例如此答案中链接的排序)比用于对整数或 float 等简单元素数组进行排序的基本合并排序大约 15%。但是,如果增强快速排序以避免 O(n^2) 的最坏情况时间复杂度,则优势会降低,主要优势是它不需要合并排序所需的 O(n) 空间来进行合并操作。一般来说,归并排序比快速排序做更多的移动但更少的比较。如果对指向对象的指针数组进行排序,比较开销会大于移动指针所需的时间,并且归并排序最终会更快。另一方面,对指向对象的指针数组进行排序涉及随机访问这些对象,这对缓存不友好,并且排序对象而不是指针更快,除非对象相当大(权衡通常是128 到 256 字节,具体取决于系统)。
关于performance - 快速排序与。归并排序性能分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52601913/
本文实例汇总了Java各种排序算法。分享给大家供大家参考,具体如下: 1. 冒泡排序: ?
1.冒泡排序 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。 算法步
前言 平时用惯了高级语言高级工具高级算法,难免对一些基础算法感到生疏。但最基础的排序算法中实则蕴含着相当丰富的优化思维,熟练运用可起到举一反三之功效。 选择排序 选择排序几乎是
我是一名优秀的程序员,十分优秀!