【问题标题】:Quicksort returning unsorted middle/median element?快速排序返回未排序的中间/中值元素?
【发布时间】:2012-05-22 09:08:27
【问题描述】:

我对编程很陌生,并且已经学习了一段时间的排序算法。我在 C 中实现了下面的快速排序。它使用三个分区的中值来选择枢轴。 代码的问题是每次我运行它时,应该是排序数组的中值/中间值的元素是未排序的,即它出现在其他地方。 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
    return ;
}

int median3(int a[], int left, int right)//Uses median of three partitioning technique
{
    int center = (left + right)/2;
    if (a[center] < a[left]) 
        swap(&a[left],&a[center]);
    if (a[right] < a[left])
        swap(&a[left],&a[right]);
    if (a[right]< a[center])
        swap(&a[center],&a[right]);

    swap(&a[center], &a[right - 1]);//since the largest is already in the right.
    return a[right - 1];
}

void quicksort(int a[], int left, int right)
{
  if (left < right) {
    int pivot = median3(a,left,right);
    int i = left;
    int j = right - 1;
    for ( ; ;) {
        while(a[++i]<pivot) {} 
        while(pivot<a[--j]) {} 
        if ( i < j)
            swap(&a[i],&a[j]);
        else
            break ;
    }
    swap(&a[i],& a[right -1]);
    quicksort(a,left,i-1);
    quicksort(a,i+1,right);
  }
    return ;
}

int main(int argc, char* argv[])
{
    int i;
    int a[] = {8,1,4,9,6,3,5,2,7,0};
    quicksort(a,0,9);
    for ( i = 0 ; i < 10 ; i++)
        printf("%d\n",a[i]);
    return 0;
}

【问题讨论】:

  • 您是否尝试在调试器中单步执行代码以查看实际发生的情况?
  • 您的实现是错误的,不仅是“重新排列未排序的中间/中值元素”,更改您的测试数据您会看到输出混乱。我建议你重新学习算法并重新编写代码。

标签: c algorithm sorting


【解决方案1】:

注意边缘情况,left == right - 1:

void quicksort(int a[], int left, int right)
{
  if (left < right) {
    int pivot = median3(a,left,right);
    if (left == right - 1) return;  // only two elements, already sorted by median3()
    int i = left;
    int j = right - 1;

http://ideone.com/X5Ydx

【讨论】:

  • 特别是while(pivot&lt;a[--j]) {}会访问left之前的数组,如果left == 0是UB。
  • 非常感谢您的帮助。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 2020-06-21
相关资源
最近更新 更多