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

链表排序程序提交后提示‘排序不稳定’问题求助

链表排序不稳定问题排查与修复

问题描述

开发链表排序程序,测试反馈“排序不稳定”。排序规则:ascending=0时执行降序排序,其他值执行升序排序,排序采用区分大小写的字母序。相关代码片段如下:

TITEM *sortInsert( TITEM *newNode, TITEM *sorted)
{
   // if( sorted || strcmp(sorted->m_Name, newNode->m_Name) == 0 )
   //   return sorted;

    if( !sorted || strcmp(sorted->m_Name, newNode->m_Name) >= 0 )
    {
      newNode->m_Next = sorted;
      sorted = newNode;
    }
    else //Locate the node before the point of insertion
    {
      TITEM *tmp = sorted;
   
      while(tmp->m_Next && strcmp(tmp->m_Next->m_Name, newNode->m_Name) < 0 )
      {
        tmp = tmp->m_Next;
      }
      
      newNode->m_Next = tmp->m_Next;
      tmp->m_Next = newNode;
    }
 

  return sorted;
}

TITEM *sortList ( TITEM *l, int ascending )
{
  TITEM *tmp = l;
  TITEM *sorted = NULL;


  while(tmp)
  {
    TITEM *next = tmp->m_Next;
    sorted = sortInsert(tmp, sorted);
    tmp = next;
  }
  l = sorted;

  if( !ascending )
  {
    l = reverse(l);
  }

  return l;
}

问题根源

  1. 升序插入逻辑破坏稳定性:
    稳定排序要求相等元素保持原有相对顺序,但原代码中strcmp(sorted->m_Name, newNode->m_Name) >= 0的条件,当元素相等时(strcmp返回0),会将新节点插入到当前节点前面,直接打乱了原顺序。
  2. 降序反转操作破坏稳定性:
    先升序排序再反转链表的方式,会颠倒所有元素的顺序,包括原本相等元素的相对位置,进一步破坏稳定性。

修复方案

1. 修复升序插入的稳定性

修改sortInsert的判断条件,仅在当前节点元素严格大于新节点时才插在前面;相等元素则遍历到所有相等元素的末尾再插入,保留原顺序:

TITEM *sortInsert( TITEM *newNode, TITEM *sorted)
{
    if( !sorted || strcmp(sorted->m_Name, newNode->m_Name) > 0 )
    {
      newNode->m_Next = sorted;
      sorted = newNode;
    }
    else
    {
      TITEM *tmp = sorted;
      while(tmp->m_Next && strcmp(tmp->m_Next->m_Name, newNode->m_Name) <= 0 )
      {
        tmp = tmp->m_Next;
      }
      
      newNode->m_Next = tmp->m_Next;
      tmp->m_Next = newNode;
    }
    return sorted;
}

2. 修复降序排序的稳定性

放弃“先升序再反转”的方式,直接根据排序方向调整插入逻辑,保证相等元素的相对顺序:

// 新增带排序方向的插入函数
TITEM *sortInsertWithOrder( TITEM *newNode, TITEM *sorted, int ascending )
{
    if( !sorted )
    {
      newNode->m_Next = sorted;
      sorted = newNode;
    }
    else if( ascending )
    {
      // 升序规则:当前节点>新节点时插前面,相等则往后找
      if( strcmp(sorted->m_Name, newNode->m_Name) > 0 )
      {
        newNode->m_Next = sorted;
        sorted = newNode;
      }
      else
      {
        TITEM *tmp = sorted;
        while(tmp->m_Next && strcmp(tmp->m_Next->m_Name, newNode->m_Name) <= 0 )
        {
          tmp = tmp->m_Next;
        }
        newNode->m_Next = tmp->m_Next;
        tmp->m_Next = newNode;
      }
    }
    else
    {
      // 降序规则:当前节点<新节点时插前面,相等则往后找
      if( strcmp(sorted->m_Name, newNode->m_Name) < 0 )
      {
        newNode->m_Next = sorted;
        sorted = newNode;
      }
      else
      {
        TITEM *tmp = sorted;
        while(tmp->m_Next && strcmp(tmp->m_Next->m_Name, newNode->m_Name) >= 0 )
        {
          tmp = tmp->m_Next;
        }
        newNode->m_Next = tmp->m_Next;
        tmp->m_Next = newNode;
      }
    }
    return sorted;
}

// 修改排序主函数
TITEM *sortList ( TITEM *l, int ascending )
{
  TITEM *tmp = l;
  TITEM *sorted = NULL;

  while(tmp)
  {
    TITEM *next = tmp->m_Next;
    sorted = sortInsertWithOrder(tmp, sorted, ascending);
    tmp = next;
  }
  return sorted;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:50:43