简体   繁体   English

使用导致段错误的指针进行快速排序

[英]Quicksort with pointers causing segfault

I'm trying to take the standard quicksort algorithm and slightly modify it by taking the partition function and making it so that instead of taking the entire array, a low index and a high index, it takes in a pointer to the low'th element as well as how many elements I want to partition.我正在尝试采用标准的快速排序算法,并通过采用分区 function 并对其进行稍微修改,而不是采用整个数组、低索引和高索引,而是采用指向低元素的指针以及我要划分的元素数量。 However, I'm getting a segmentation fault and I can't figure it out.但是,我遇到了分段错误,我无法弄清楚。 Thanks for the help.谢谢您的帮助。

#include <stdio.h>

void swap(int *a, int *b) {
  int t = *a;
  *a = *b;
  *b = t;
}

int partition(int *array, int high) {
  int pivot = array[high];
  int i = 0;

  for (int j = 0; j < high; j++) {
    if (array[j] <= pivot) {
      swap(&array[i++], &array[j]);
    }
  }

  swap(&array[i], &array[high]);
  return i;
}

void quickSort(int *array, int low, int high) {
  if (low < high) {
    int pi = partition(array + low, high - low);
    quickSort(array, low, pi - 1);
    quickSort(array, pi + 1, high);
  }
}

void printArray(int array[], int size) {
  for (int i = 0; i < size; ++i) {
    printf("%d  ", array[i]);
  }
  printf("\n");
}

int main() {
  int data[] = {8, 7, 2, 1, 0, 9, 6};
  
  int n = sizeof(data) / sizeof(data[0]);
  
  printf("Unsorted Array\n");
  printArray(data, n);
  
  // perform quicksort on data
  quickSort(data, 0, n - 1);
  
  printf("Sorted array in ascending order: \n");
  printArray(data, n);
}

Given the following in your code:在您的代码中给出以下内容:

int pi = partition(array + low, high - low);
quickSort(array, low, pi - 1);
quickSort(array, pi + 1, high);

You're partitioning using a pointer-adjusted base ( array+low ), and segment pure length ( high-low ).您正在使用指针调整的基数 ( array+low ) 和分段纯长度 ( high-low ) 进行分区。 That's fine if that is how your partition implementation works (most do).如果这就是您的分区实现的工作方式(大多数情况下如此),那很好。 But you need to remember the resulting pivot location, pi , will be based on a position in that segment;但是您需要记住生成的 pivot 位置pi将基于该段中的 position; not in the overall array.不在整体阵列中。 You need to adjust for that when recursing by putting back the original offset from whence that partition was configured:在递归时,您需要通过从配置该分区的位置放回原始偏移量来对此进行调整:

int pi = partition(array + low, high - low);
quickSort(array, low, low + pi - 1);   // <== LOOK
quickSort(array, low + pi + 1, high);  // <== HERE

That change alone should get your implementation running.仅此更改就应该使您的实施运行起来。 There are other ways to do this, and I'll update this answer with a couple of them when/if I find the time.还有其他方法可以做到这一点,如果我有时间,我会用其中的几个来更新这个答案。

Alternate version of a pointer based quicksort using Hoare partition scheme:使用 Hoare 分区方案的基于指针的快速排序的替代版本:

void QuickSort(int *lo, int *hi)
{
int *i, *j;
int p, t;
    if(lo >= hi)
        return;
    p = *(lo + (hi-lo)/2);
    i = lo - 1;
    j = hi + 1;
    while (1){
        while (*(++i) < p);
        while (*(--j) > p);
            if (i >= j)
                break;
            t = *i;
            *i = *j;
            *j = t;
    }
    QuickSort(lo, j);
    QuickSort(j+1, hi);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM