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

按年龄优先、同年龄按字母序排序人员信息时输出异常求助

选择排序逻辑错误排查:年龄相同姓名字母序逆序问题

问题背景

需求:对人员信息列表按年龄升序排序,年龄相同时按姓名字母序升序排列。实现的C语言选择排序代码在大部分场景正常,但给定测试输入时,出现15岁的Mary排在Anna之前的错误结果。

测试输入

5
Gilbert 35
Anna 35
Anna 15
Mary 15
Joseph 40

原代码

#include <stdio.h>
#include <string.h>

struct people{
    char name[30];
    int age;
};

int main(){
    int n, i, j, min, tmp1;
    scanf("%d", &n);
    struct people person[n], temp;

    for(i = 0; i < n; i++){
        scanf("%s%d", person[i].name, &(person[i].age));
    }
    
    // SELECTION SORT
    for(i = 0; i < n - 1; i++){
        min = i;
        for(j = i + 1; j < n; j++){
            if (person[j].age < person[i].age ||
                strcmp(person[j].name,person[min].name) < 0 && person[j].age == person[min].age){
                min = j;
            }
        }
        if(min != i){
            temp.age = person[i].age;
            person[i].age = person[min].age;
            person[min].age = temp.age;

            strcpy(temp.name, person[i].name);
            strcpy(person[i].name, person[min].name);
            strcpy(person[min].name, temp.name);
        }
    }

    for(i = 0; i < n; i++){
        printf("%s %d\n", person[i].name, (person[i].age));
    }
}

错误现象

输出中Mary 15排在Anna 15之前,不符合姓名字母序升序的要求。

错误原因

核心问题出在选择排序的比较条件逻辑:

  1. 错误的比较基准:原代码第一个条件person[j].age < person[i].age是将当前j位置的元素与轮次起始元素person[i]比较,而非当前记录的最小元素person[min]。这会导致当遇到同年龄的元素时,只要年龄小于person[i],就直接更新min,忽略了同年龄下的名字字典序比较。
  2. 以测试输入为例:当i=0(对应Gilbert 35),j遍历到Anna 15时,15 < 35成立,min被设为2;继续遍历到Mary 15时,15 < 35依然成立,min被错误更新为3,最终导致Mary被交换到i=0的位置,出现逆序。

修复方案

修正比较逻辑,始终以当前min位置的元素为基准:

  • 先判断j位置元素的年龄是否小于min位置元素的年龄,是则更新min;
  • 若年龄相等,再判断j位置元素的名字字典序是否小于min位置元素的名字,是则更新min。

同时优化结构体交换方式,直接交换整个结构体,避免分开复制字段的冗余和错误。

修复后的代码

#include <stdio.h>
#include <string.h>

struct people{
    char name[30];
    int age;
};

int main(){
    int n, i, j, min;
    scanf("%d", &n);
    struct people person[n], temp;

    for(i = 0; i < n; i++){
        scanf("%s%d", person[i].name, &(person[i].age));
    }
    
    // SELECTION SORT
    for(i = 0; i < n - 1; i++){
        min = i;
        for(j = i + 1; j < n; j++){
            // 正确的比较逻辑:先比年龄,年龄相等再比名字字典序
            if (person[j].age < person[min].age || 
                (person[j].age == person[min].age && strcmp(person[j].name, person[min].name) < 0)){
                min = j;
            }
        }
        if(min != i){
            temp = person[i]; // 直接交换整个结构体
            person[i] = person[min];
            person[min] = temp;
        }
    }

    for(i = 0; i < n; i++){
        printf("%s %d\n", person[i].name, person[i].age);
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:56:01