Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 快速排序算法中的分段错误(堆芯转储)_C_Segmentation Fault_Quicksort - Fatal编程技术网

C 快速排序算法中的分段错误(堆芯转储)

C 快速排序算法中的分段错误(堆芯转储),c,segmentation-fault,quicksort,C,Segmentation Fault,Quicksort,下面是我的代码快速排序IC。我得到分段错误核心转储。 我努力想解决这个问题,但什么也没找到 #include<stdio.h> int divide(int a[], int p, int q) { int mid, i, lastsmall, temp; mid = (p + q)/2; temp = a[mid]; a[mid] = a[p]; a[p] = temp; int pivot = a[p]; lastsma

下面是我的代码快速排序IC。我得到分段错误核心转储。
我努力想解决这个问题,但什么也没找到

#include<stdio.h>

int divide(int a[], int p, int q) {
    int mid, i, lastsmall, temp;

    mid = (p + q)/2;
    temp = a[mid];
    a[mid] = a[p];
    a[p] = temp;
    int pivot = a[p];
    lastsmall = p;

    for (i = p + 1; i <= q; i++) {
        if (a[p] > pivot)
            continue;
        else {
             lastsmall++;
             temp = a[i];
             a[i] = lastsmall;
             lastsmall = a[i];
        }
    }
    return lastsmall;
}

void quick(int a[], int p, int q) {
    int pivot;
    if (p < q) {
        pivot = divide(a, p, q);
        quick(a, p, pivot);
        quick(a, pivot + 1, q);
    }
}

int main() {
    int ar[10], i;

    printf("Enter the list\n");
    for (i = 0; i < 10;i++)
        scanf("%d", &ar[i]);
    quick(ar, 0, 9);
    for (i = 0; i < 10; i++)
        printf("%d ", ar[i]);
    return 0;
}
编辑以添加一些解释

在26号线路上很容易找到SEG故障,一个接一个断开。我无法理解您的divide函数,所以我只是在的伪代码之后实现了对pivot的搜索。发现简单易懂

#include<stdio.h>
int divide(int a[], int low, int high)
{
  int pivot, tmp;

  // Yes, you can choose other start values.
  pivot = (low + high)/2;

  while (low <= high) {
    while (a[low] < a[pivot]) {
      low++;
    }
    while (a[high] > a[pivot]) {
      high--;
    }
    if (low <= high) {
      tmp = a[low];
      a[low] = a[high];
      a[high] = tmp;
      low++;
      high--;
    }
  }
  return pivot;
}

void quick(int a[], int p, int q)
{
  int pivot;
  if (p < q) {
    pivot = divide(a, p, q);
    // Here was your segfault
    quick(a, p, pivot - 1);
    quick(a, pivot + 1, q);
  }
}

int main()
{
  int ar[10], i;
  printf("Enter the list\n");
  for (i = 0; i < 10; i++) {
    scanf("%d", &ar[i]);
  }
  quick(ar, 0, 9);
  for (i = 0; i < 10; i++) {
    printf("%d ", ar[i]);
  }
  return 0;
}
一个真正的实现将涉及大量的指针处理、一个比较元素的函数、作为函数指针传递的函数以及大量优化。请参见示例

上述编辑承诺:

枢轴本身可以通过任何方式进行转换,只要它在输入中的某个位置,它甚至可以是常量,就像我之前所做的那样。许多论文都写过关于轴心选择的文章,他们唯一的共同点是结论:这取决于预期的输入

我已经在外部while循环prob中放置了一个计数器。更好的方法是计算比较次数,并生成100个10到10000之间的随机整数一百次。返回的平均轮数为

低=168.55 -低=185.67 高=inf ++高=174.87 pivot=216.04,即:始终是每秒钟递增一次的开始索引 如果我把轴改成几何平均数的底面

低=153.22 -低=152.65 高=inf ++高=151.88 枢轴=134.85 计算10到1000000 pivot之间100000个随机整数元素数组的实际比较数,仍然是100次运行的几何平均值

低=12762491.95 -低=12756154.17 高=inf ++高=12702092.52 枢轴=13121675.81 轴设置为几何平均值时也是如此

低=12749755.60 -低=12801865.60 高=inf ++高=12705592.10 枢轴=13113604.20 有些人可能会说,快速调用除法的调用数比使用常数因子的调用数的一半多一点,这是一个更好的度量方法,他们也是正确的。这次只有10发子弹

同样的

低=1281068.00 -低=1225781.20 高=inf ++高=1221477.00 枢轴=1048575.00 相同,输入从低到高排序

低=1280983.80 -低=1225749.80 高=inf ++高=1221376.80 枢轴=1048575.00 相同,输入从高到低排序

低=1281025.80 -低=1225738.80 高=inf ++高=1221632.20 枢轴=1048575.00 使用WhozCraig提议的分界进行测试:

未分类输入:1333671.00 已排序输入从低到高:1333513.60 已排序输入从高到低:1333594.80

稳定的运行时,但对于给定的输入,运行时也会稍微慢一点,但要慢一点

结论:对于均匀分布、随机、密集的输入集,将轴设置为低和高之间的几何平均值似乎可以节省大部分比较。返回起始轴或稍后计算的一个更优化的值在比较中有一个重要但非常小的差异,但在实际调用quick时有一个相当大的差异

对于其他输入集和其他轴值,这将有所不同。您也可以使用多个轴,并且对于不同的体系结构也是如此


优化快速排序确实可能会浪费很多时间,所以要小心

我努力想解决这个问题,但一无所获。。你发现了什么?至少您应该能够告诉我们是哪一行代码导致seg故障。调试器将为您提供这些信息和更多信息。即使没有调试器,您是否尝试阅读代码并了解每一行的实际操作;lastsall=a[i]??和ifa[p]>pivot continue@WhozCraig Yepp,这是个打字错误。从C&P将一个函数转换为OP生成的两个函数。是什么阻止你修复这个明显的错误?