You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何arrayone与arraytwo排序输出不一致?如何修复?

修复分段有序数组自定义排序函数MySort的问题

我编写了如下C语言代码,实现基于分段有序数组的自定义排序函数MySort:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int FindMid(int array[], int n) {
  int i;
  int m = 0;
  for (i = 0; i < n; i++) {
    if (i < n - 1 && array[i] > array[i + 1])
      m = i + 1;
  }
  return m;
}

void MySort(int array[], int n) {

  int i = 0;
  int l = 0;
  int t = FindMid(array, n);
  int m = t;
  int k = 0;
  int *temp = (int *)malloc(sizeof(int) * n * 2);

  for (i = 0; i < n; i++) {
    temp[i] = 0;
  }

  while (l < m && m < n) {
    if (array[l] <= array[m]) {
      temp[k++] = array[l++];
    } else {
      temp[k++] = array[m++];
    }
  }

  while (l < t) {
    temp[k++] = array[l++];
  }
  while (m < n) {
    temp[k++] = array[m++];
  }

  for (i = 0; i < n; i++) {
    array[i] = temp[i];
  }

  free(temp);
}

void print_ary(int *pa, int n) {
  int i;

  for (i = 0; i < n; i++) {
    printf("%d ", pa[i]);
  }
  printf("\n");
}

int main(void) {
  int arrayone[13] = {1, 6, 9, 16, 21, 2, 5, 11, 19, 25, 30, 33, 40};
  int arraytwo[13] = {1, 6, 9, 16, 21, 25, 30, 33, 40, 2, 5, 11, 19};
  int a = 13;
  MySort(arrayone, a);
  print_ary(arrayone, a);
  MySort(arraytwo, a);
  print_ary(arraytwo, a);

  return 0;
}

预期对arrayone和arraytwo排序后输出一致:

1 2 5 6 9 11 16 19 21 25 30 33 40
1 2 5 6 9 11 16 19 21 25 30 33 40

但实际输出不同:

1 2 5 6 9 11 16 19 21 2 5 11 19
1 2 5 6 9 11 16 19 21 25 30 33 40

我怀疑问题出在while(m<n){temp[k++]=array[m++]}语句,尝试将其替换为以下代码后结果仍无改善:

for (i = 0; i < n; i++) {
  if (temp[k - 1] < array[i]) {
    while (k < n) {
      temp[k++] = array[k++];
    }
  }
}

请问该如何修复这个问题?


问题根源

FindMid函数逻辑错误:它会遍历整个数组,每次遇到array[i] > array[i+1]就更新m为i+1。对于arrayone这种存在多段有序分段的数组(前5个元素有序、中间4个有序、最后4个有序),FindMid最终返回的是最后一个分段的起始位置(索引9),而非第一个分段结束后的起始点(索引5)。这导致归并逻辑只处理了前一段(08)和最后一段(912),漏掉了中间的分段(5~8),所以排序后中间段元素被遗留到末尾。

修复方案

1. 修正FindMid函数

让它找到第一个逆序对后立即返回对应的分段起始位置,不再继续遍历更新:

int FindMid(int array[], int n) {
  int i;
  for (i = 0; i < n - 1; i++) {
    if (array[i] > array[i + 1])
      return i + 1; // 找到第一个逆序对直接返回
  }
  return 0; // 数组完全有序时返回0
}

2. 优化MySort函数

  • 增加数组已完全有序的判断,直接返回避免无效计算
  • 调整归并循环的判断条件,确保覆盖两个完整的有序分段
  • 缩减临时数组的空间(只需n个元素即可)

修改后的MySort:

void MySort(int array[], int n) {
  int i = 0;
  int l = 0;
  int t = FindMid(array, n);
  
  // 数组已完全有序,无需处理
  if (t == 0) return;
  
  int m = t;
  int k = 0;
  int *temp = (int *)malloc(sizeof(int) * n); // 仅需n个元素空间

  while (l < t && m < n) {
    if (array[l] <= array[m]) {
      temp[k++] = array[l++];
    } else {
      temp[k++] = array[m++];
    }
  }

  // 处理前一段剩余元素
  while (l < t) {
    temp[k++] = array[l++];
  }
  // 处理后一段剩余元素
  while (m < n) {
    temp[k++] = array[m++];
  }

  for (i = 0; i < n; i++) {
    array[i] = temp[i];
  }

  free(temp);
}

效果验证

修改后,arrayone和arraytwo都能输出预期的正确排序结果。


内容的提问来源于stack exchange,提问作者kookoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 09:49:52