快速排序返回未排序的中间/中值元素?

Posted

技术标签:

【中文标题】快速排序返回未排序的中间/中值元素?【英文标题】: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;

【问题讨论】:

您是否尝试在调试器中单步执行代码以查看实际发生的情况? 您的实现是错误的,不仅是“重新排列未排序的中间/中值元素”,更改您的测试数据您会看到输出混乱。我建议你重新学习算法并重新编写代码。 【参考方案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。 非常感谢您的帮助。 :)

以上是关于快速排序返回未排序的中间/中值元素?的主要内容,如果未能解决你的问题,请参考以下文章

C和Python实现快速排序-三数中值划分选择主元(非随机)

快速排序/快速选择算法

快速选择算法

快速排序的错误

排序算法之快速排序

快速排序