[英]Merge sort 3 way split C
Sorry for annoying anyone here, but I'm having an issue with my merge sort code. 抱歉让这里的任何人烦恼,但是我的合并排序代码有问题。 Previously I could code the 2-way merge sort and when I tried to adapt my merge sort to be an 3-way merge sort my compiler gave me:
9154 segmentation fault(core dumped)
. 以前,我可以编写2向合并排序的代码,当我尝试将合并排序调整为3向合并排序时,我的编译器给了我:
9154 segmentation fault(core dumped)
。 Could you help me to fix this? 你能帮我解决这个问题吗? there is my code:
有我的代码:
#include <stdio.h>
void merge(int v[], int p, int q, int r) {
int i, j, k, b[10];
for (i = p; i <= q; i++) {
b[i] = v[i];
}
for (j = q + 1; j <= r; j++) {
b[r + q + 1 - j] = v[j];
}
i = p;
j = r;
for (k = p; k <= r; k++) {
if (b[i] <= b[j]) {
v[k] = b[i];
i++;
} else {
v[k] = b[j];
j--;
}
}
}
void mersort(int v[], int p, int r) { //2-way mergesort that works
int q;
if (p < r) {
q = (p + r) / 2;
mersort(v, p, q);
mersort(v, q + 1, r);
merge(v, p, q, r);
}
}
void mersort3(int v[], int p, int r) {//not working
int q, s;
if (r > p) {
q = p + (p + r) / 3;
s = p + 2 * ((p + r) / 3) + 1;
mersort3(v, p, q);
mersort3(v, q, s);
mersort3(v, s, r);
merge(v, p, q, s);
merge(v, p, s, r);
}
}
Your main problems are due to out-of-range indexing due to improper index calculations, and potential infinite recursion for the same reason. 您的主要问题是由于索引计算不正确而导致索引超出范围,以及出于相同原因的潜在无限递归。
You're overcomplicating this tremendously. 您使这个复杂化了很多。 One of the beautiful advantages to C is pointer arithmetic , which makes things like sequence partitioning and traversals like this much, much simpler.
C的美丽优点之一是指针算法 ,它使诸如序列划分和遍历这样的事情变得非常简单。 As a bonus, you also get to remove one of your function arguments, as the only reason it is there is the base-adjustment, which is taken care of with the pointer arithmetic.
另外,您还可以删除一个函数参数,这是它存在基址调整的唯一原因,该调整由指针算术解决。
For example, a simple VLA-based merge algorithm (obviously, don't invoke this with a large sequence) 例如,一个简单的基于VLA的合并算法(显然,请勿大序列调用此算法)
/* a simple little VLA-based merge. don't invoke with huge arrays */
void merge(int v[], size_t mid, size_t len)
{
if (len < 2)
return;
size_t i=0, j=mid, k=0;
int tmp[len];
while (i < mid && j < len)
tmp[k++] = (v[i] < v[j]) ? v[i++] : v[j++];
memcpy(tmp+k, v+i, (mid-i) * sizeof *v);
memcpy(v, tmp, (k + (mid-i)) * sizeof *v);
}
Well, not a great showcase of pointer arithmetic, but there's some in there. 好吧,这不是一个很好的指针算法展示,但是里面有一些。 The place where it really shines is the partitioning algorithms.
真正发挥作用的地方是分区算法。 For example, a simple merge sort:
例如,一个简单的合并排序:
void mersort(int v[], size_t len)
{
if (len < 2)
return;
size_t mid = len/2;
mersort(v, mid);
mersort(v+mid, len-mid); // see here.
merge(v, mid, len);
}
Extending this to a three-way partitioning scheme becomes: 将其扩展为三向分区方案将成为:
void mersort3(int v[], size_t len)
{
if (len < 3)
{
mersort(v, len);
return;
}
size_t m1 = len/3;
size_t m2 = (2 * len)/3;
mersort3(v, m1);
mersort3(v+m1, m2-m1); // see here
mersort3(v+m2, len-m2); // and here
merge(v, m1, m2);
merge(v, m2, len);
}
An example invoke that uses a guaranteed-unusual partition size is below (the sequence is 29 elements long) 下面是使用保证的异常分区大小的示例调用(序列长29个元素)
int main()
{
srand((unsigned)time(NULL));
const size_t N = 29;
size_t i,j;
int ar[N], n=0;
// build a sequence from 1..29
for (i=0; i<N; ++i)
ar[i] = ++n;
// shuffle the sequence
for (i=0; i<3; ++i)
{
for (j=0; j<N; ++j)
{
n = rand() % N;
int tmp = ar[n];
ar[n] = ar[j];
ar[j] = tmp;
}
}
// show the shuffled sequence
for (i=0; i<N; ++i)
printf("%d ", ar[i]);
fputc('\n', stdout);
// sort it
mersort3(ar, N);
// show it again
for (i=0; i<N; ++i)
printf("%d ", ar[i]);
fputc('\n', stdout);
return EXIT_SUCCESS;
}
Output (shuffled sequence varies) 输出 (混排顺序不同)
21 8 11 27 18 9 17 28 20 14 15 1 29 6 19 22 7 2 16 23 5 12 4 3 10 26 13 25 24
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.