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

如何在C语言链表中按姓名字母顺序插入Person节点?

按姓名字母顺序插入链表节点的实现方案

下面是修改后的完整代码,替换了原有的尾插逻辑,实现了按姓名字母顺序插入节点,同时处理了新节点需要成为链表头的情况:

#define _CRT_SECURE_NO_WARNINGS
#define PAUSE system("pause")
#define CLS system ("cls")
#define FLUSH myFlush();
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <ctype.h>
#include<time.h>

//Function Prototypes
void displayMenu();
int getChoice(int* option);
void myFlush();
Person* createPerson(const char* name, int age, float weight);
void insertSorted(LIST* head, Person* newNode);

typedef struct personType 
{
    char name[100];
    int age;
    float weight;
    struct personType* next;
}Person;

typedef Person* LIST;

int main() {
    LIST start = NULL; // 只保留头节点指针即可,无需linkedList变量
    int ageTemp = 0, counter;
    char nameTemp[100], response;
    float weightTemp;
    int option;
    do {
        getChoice(&option);
        switch (option)
        {
        case 1:
            do 
            {
                CLS;
                printf("\nEnter a name for person : ");
                scanf("%[^\t\n]", nameTemp); FLUSH;

                printf("\nEnter the age for %s: ", nameTemp);
                scanf("%i", &ageTemp); FLUSH;

                printf("\nEnter the weight for %s: ", nameTemp);
                scanf("%f", &weightTemp); FLUSH;

                // 创建新节点并插入有序链表
                Person* newNode = createPerson(nameTemp, ageTemp, weightTemp);
                insertSorted(&start, newNode);

                printf("\nWould you like to enter another person?");
                printf("\nEnter Y/N: ");
                scanf("%c", &response); FLUSH;
            } while (response == 'Y' || response == 'y');
            CLS;
            break;
        case 2:
            LIST temp = start;
            CLS;
            counter = 1;
            while (temp != NULL)
            { 
                printf("Person %i: %s\t Age: %2i Weight: %.2f \n",
                    counter, temp->name, temp->age, temp->weight);
                counter += 1;
                temp = temp->next;
            }
            printf("\n\n");
            PAUSE;
            CLS;
            break;
        case 3:
            printf("Exiting program...\n");
            printf("See you next time :)");
            break;
        default:
            CLS;
            printf("That was not a valid selection...");
            PAUSE;
        }
    } while (option != 3);

    // 释放内存
    while (start != NULL)
    { 
        LIST temp = start;
        start = start->next;
        free(temp);
    }
    return 0;
}

// 创建新的Person节点
Person* createPerson(const char* name, int age, float weight) {
    Person* newNode = (Person*)malloc(sizeof(Person));
    strcpy(newNode->name, name);
    newNode->age = age;
    newNode->weight = weight;
    newNode->next = NULL;
    return newNode;
}

// 按姓名字母顺序插入节点,支持更新头节点
void insertSorted(LIST* head, Person* newNode) {
    // 情况1:链表为空,直接作为头节点
    if (*head == NULL) {
        *head = newNode;
        return;
    }

    // 情况2:新节点比头节点的名字更靠前,更新头节点
    if (strcmp(newNode->name, (*head)->name) < 0) {
        newNode->next = *head;
        *head = newNode;
        return;
    }

    // 情况3:遍历找到插入位置,用prev跟踪前驱节点
    LIST current = *head;
    LIST prev = NULL;
    while (current != NULL && strcmp(newNode->name, current->name) >= 0) {
        prev = current;
        current = current->next;
    }

    // 插入到prev和current之间
    prev->next = newNode;
    newNode->next = current;
}

void myFlush()
{
    while (getchar() != '\n');
}

void displayMenu()
{
    CLS;
    printf("Please select from the following options:\n\n");
    printf("1. Add a Record.\n");
    printf("2. Display All Records.\n");
    printf("3. Quit.\n\n\n");
    printf("Please enter a selection: ");
}

int getChoice(int* option)
{
    displayMenu();
    scanf("%i", option); FLUSH;
    return toupper(*option);
}

关键修改说明

  1. 新增模块化函数

    • createPerson:负责创建并初始化新节点,简化主函数逻辑
    • insertSorted:核心的有序插入函数,处理所有插入场景
  2. 有序插入逻辑拆解

    • 空链表直接插入:如果head是NULL,新节点就是头节点
    • 插入到头部:用strcmp比较新节点和头节点的名字,若返回值小于0,说明新节点名字更靠前,直接将新节点的next指向原头,再更新head指针
    • 插入到中间/尾部:用双指针current和prev遍历链表,找到第一个比新节点名字大的节点位置,插入到prev之后
  3. 原代码冗余清理

    • 移除了linkedList和count变量,因为有序插入不需要跟踪尾节点或计数
    • 修正了main函数的返回值(原代码未写return 0,不符合C标准)
    • 优化了getChoice函数中的scanf参数(&*option简化为option)
  4. 字符串比较说明

    • 代码中用strcmp做区分大小写的字母序比较,如果需要忽略大小写,可以替换为strcasecmp(Linux/macOS),或者自己实现忽略大小写的比较函数:
      int strcasecmp_custom(const char* a, const char* b) {
          while (*a && *b) {
              if (toupper(*a) != toupper(*b)) {
                  return toupper(*a) - toupper(*b);
              }
              a++;
              b++;
          }
          return *a - *b;
      }
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:07:14