【问题标题】:Quicksort doesn't work for the last two numbers快速排序不适用于最后两个数字
【发布时间】:2023-03-08 18:26:01
【问题描述】:

任务是为数组中未知类型的元素编写快速排序(仅使用 C 代码),但我的代码不适用于最后两个元素。对于以下数字输出是 '67 45 44 33 5 1 -3 0 -4 -100' 我也尝试调试,但我唯一理解的是最后一个数字不能比较。

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <memory.h>
typedef int typeEl;

void swap(void* a, void* b, size_t sizeOfElem) {
    void* tmp = calloc(1,sizeOfElem);
    memcpy(tmp, a, sizeOfElem);
    memcpy(a, b, sizeOfElem);
    memcpy(b, tmp, sizeOfElem);
}

int compare(const void* a, const void* b)
{

    return (*(typeEl*)a - *(typeEl*)b);
}

void quickSortR(void* a, long N, size_t sizeOfElem, int (*comp)(const void* c, const void* d)) 
{

  long i = 0, j = N;        


  void* p = (void *) ((char *)a + (N>>1)*sizeOfElem);       

  do {
    while ( comp((void *) ((char *)a + i*sizeOfElem), p)>0) i++;
    while ( comp((void *) ((char *)a + j*sizeOfElem), p)<0) j--;

    if (i <= j) {
      swap((void *) ((char *)a + i*sizeOfElem), (void *) ((char *)a + j*sizeOfElem), sizeOfElem);
      i++; j--;
    }
  } while ( i<=j );


  if ( j > 0 ) quickSortR((void *)a, j, sizeOfElem, comp);
  if ( N > i ) quickSortR((void *) ((char *)a + i*sizeOfElem), N-i,sizeOfElem, comp);
}
int main() {
    int n;
   int m[10] = {1,-3,5,-100,45,33,44,67,-4, 0};

   quickSortR((void *)m, 10, sizeof(int),compare);              
    for (n=0; n<10; n++)
        printf ("%d ",m[n]);
   return 0;
}

谁能给点建议? 谢谢帮忙!

【问题讨论】:

    标签: c algorithm sorting quicksort


    【解决方案1】:

    您的代码中有 3 个问题:

    1. j = N的初始化应为j = N - 1。原因:稍后你使用j位置的元素开始比较,C中的数组索引为[0,N-1]

    2. 枢轴p 不应是指针,而是值。当位置 p 的值被交换但您仍将其视为枢轴时,这会影响结果。您的代码似乎是为与指针进行比较而设计的,但是我可以提出一个快速而丑陋(也很危险!)的修复:
      替换你的代码:

      void* p = (void *) ((char *)a + (N>>1)*sizeOfElem);
      

      这些:

      void* p = (void *) ((char *)a + (N>>1)*sizeOfElem);
      void *px = malloc(sizeOfElem);
      memcpy(px, p, sizeOfElem);
      p = px;
      
    3. 这行代码:

      if ( j > 0) quickSortR((void *)a, j, sizeOfElem, comp);
      

      应该是:

      if ( j > 0) quickSortR((void *)a, j + 1, sizeOfElem, comp);
      

      因为在quickSortR 的第二个参数处,您正在传递数组的长度。

    修复所有这 3 个问题,您的代码将给出正确的结果。

    已编辑:
    当我在上面说3 problems 时,我的意思是实现算法时出现问题。除此之外,您的函数compare 中存在内存泄漏(只需free(tmp) 即可解决)。测试if ( N &gt; i ) 也可以是if ( N &gt; i + 1 )
    :)

    【讨论】:

    • 非常感谢!不仅解决了问题,还说出了为什么会这样。
    • @user1536810 嗯,很高兴(也很荣幸)能提供帮助!我仍然记得我开始编程并第一次尝试理解quick sort的日子......:D
    • @user1536810 我刚刚更新了答案,添加了一个“视觉”示例来解释问题 3。如果你能来看看就好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2017-06-23
    • 2021-12-14
    • 1970-01-01
    相关资源
    最近更新 更多