稳定合并排序C.

时间:2011-11-21 17:09:20

标签: c sorting mergesort

我正在编写一个简单的合并排序函数,以根据给定的比较函数进行排序:

void merge(int left, int mid, int right, int(*compar)(const void *, const void *))
{
  // sublist sizes
  int left_size = mid - left + 1;
  int right_size = right - mid;

  // counts
  int i, j, k;

  // create left and right arrays
  B *left_list = (B*) malloc(left_size*sizeof(B));
  B *right_list = (B*) malloc(right_size*sizeof(B));

  // copy sublists, could be done with memcpy()?
  for (i = 0; i < left_size; i++)
    left_list[i] = list[left + i];

  for (j = 0; j < right_size; j++)
    right_list[j] = list[mid + j + 1];

  // reset counts
  i = 0; j = 0;

  for (k = left; k <= right; k++)
  {
    if (j == right_size)
      list[k] = left_list[i++];
    else if (i == left_size)
      list[k] = right_list[j++];
    // here we call the given comparision function
    else if (compar(&left_list[i], &right_list[j]) < 0)
      list[k] = left_list[i++];
    else
      list[k] = right_list[j++];
  }
}

void sort(int left, int right, int(*compar)(const void *, const void *))
{
  if (left < right)
  {
    // find the pivot point
    int mid = (left + right) / 2;

    // recursive step
    sort(left, mid, compar);
    sort(mid + 1, right, compar);

    // merge resulting sublists
    merge(left, mid, right, compar);
  }
}

然后我使用不同的比较函数在相同的 list 数组上多次调用它。我发现第一次调用的排序是稳定的,但之后我看到元素交换,即使它们相等。

有人能说出这种行为的原因吗?

2 个答案:

答案 0 :(得分:3)

我不确定是否会这样做,但尝试更改此行:

compar(&left_list[i], &right_list[j]) < 0

到此:

compar(&left_list[i], &right_list[j]) <= 0

这将使它如果它们已经相等,它会做第一个动作(希望)保持稳定而不是移动东西。

这只是猜测。

答案 1 :(得分:1)

我认为你的尺码错了

int left_size = mid - left;

而且,正如arasmussen指出的那样,你需要优先选择左侧列表才能保持稳定

compar(&left_list[i], &right_list[j]) <= 0

除此之外,在购买助手列表之后,你并没有免费打电话。这不会使算法返回不正确的结果,但每次调用sort函数时都会导致程序的内存使用不可逆转地增长。