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

C语言如何将NameCard结构体数组按nameCardID升序排列

问题分析
  • 临时数组fakeHolder使用逻辑错误:仅将新名片存入fakeHolder[0],遍历原有数组时仅拷贝了ID大于新ID的元素到临时数组,ID小于新ID的元素完全没有拷贝到临时数组中,导致这部分数据丢失,最终排序结果错误。
  • ID重复校验逻辑不完整:检测到ID重复后仅打印提示,没有终止后续的新增流程,重复ID仍会被插入到数组中,且size会错误累加。
  • 插入逻辑缺失位置判断:没有提前确定新ID的插入位置,边遍历边拷贝的逻辑无法覆盖所有排序场景,连续插入更小的ID时数据顺序会完全混乱。
  • 临时数组固定长度风险:fakeHolder固定长度为10,若业务定义的最大名片数MAX大于10,会出现数组越界访问。
正确实现思路

不需要额外申请完整的临时数组,仅用单个临时结构体存储新录入的名片即可,插入逻辑如下:

  1. 首先判断当前名片数是否已达上限,满员直接返回。
  2. 录入新名片信息存储到临时结构体,先校验ID是否已存在,存在则直接返回不新增。
  3. 遍历现有有序数组,找到第一个大于新ID的元素下标pos,即为新名片的插入位置;若所有现有ID都小于新ID,pos等于当前名片数,直接追加到末尾。
  4. 将数组中从pos开始到末尾的所有元素统一向后挪动1位,空出pos位置。
  5. 将临时结构体的内容赋值到pos位置,名片数+1,完成升序插入。
修正后代码
#include <stdio.h>
#include <string.h>
#define MAX 50 // 可根据业务需求调整最大名片数

typedef struct{
    int nameCardID;
    char personName[20];
    char companyName[20];
} NameCard;

int addNameCard(NameCard *nc, int *size){
    printf("addNameCard():\n");
    if(*size == MAX){
        printf("The name card holder is full\n");
        return 0;
    }

    // 仅用单个临时结构体存储新名片
    NameCard newCard;
    char dummy;
    char *p;

    printf("Enter nameCardID:\n");
    scanf("%d", &newCard.nameCardID);
    scanf("%c", &dummy); // 吃掉输入缓冲区的换行符

    printf("Enter personName:\n");
    fgets(newCard.personName, 20, stdin);
    if((p = strchr(newCard.personName, '\n')) != NULL){
        *p = '\0';
    }

    printf("Enter companyName:\n");
    fgets(newCard.companyName, 20, stdin);
    if((p = strchr(newCard.companyName, '\n')) != NULL){
        *p = '\0';
    }

    // 第一步:校验ID是否重复
    for(int j = 0; j < *size; j++){
        if(newCard.nameCardID == nc[j].nameCardID){
            printf("The nameCardID has already existed\n");
            return 0; // 重复直接返回,不执行新增
        }
    }

    // 第二步:找到插入位置pos
    int pos = 0;
    while(pos < *size && nc[pos].nameCardID < newCard.nameCardID){
        pos++;
    }

    // 第三步:将pos及之后的元素向后挪一位
    for(int j = *size; j > pos; j--){
        nc[j] = nc[j-1]; // 结构体可直接赋值,不需要逐字段拷贝
    }

    // 第四步:插入新名片,size+1
    nc[pos] = newCard;
    *size += 1;

    printf("The name card has been added successfully\n");
    return 0;
}

上述代码利用C语言结构体支持直接赋值的特性简化了字段拷贝逻辑,插入的时间复杂度为O(n),适合名片数不大的场景。如果名片数规模很大,可以用二分查找优化插入位置的查找效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:06:03