C语言中含嵌套结构列表的动态存储与排序实现咨询
C语言嵌套动态结构体实现方案
一、结构体方案完全可行
你需要的嵌套结构可以通过自定义结构体+动态内存分配实现,核心是设计包含子项指针数组的结构体,同时用变量记录子项数量。示例结构体定义如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Animal { char* name; // 动物名称(动态分配内存存储) int value; // 对应数值 struct Animal** children; // 子项动态数组指针 int child_count; // 当前子项数量 } Animal;
二、动态初始化结构的实现
因为输入数量不确定,不能用固定大小的数组,必须用malloc和realloc动态扩容:
- 父项数组的动态管理
先初始化一个初始容量的父项数组,每新增一个父项时检查是否需要扩容:
#define INIT_CAPACITY 4 int main() { Animal** animals = malloc(INIT_CAPACITY * sizeof(Animal*)); int animal_count = 0; int animal_capacity = INIT_CAPACITY; // 循环读取输入(示例:输入格式为"名称 数值",输入空行结束) char input[100]; while (fgets(input, sizeof(input), stdin) != NULL) { // 处理空行退出 if (strcmp(input, "\n") == 0) break; // 扩容父项数组 if (animal_count >= animal_capacity) { animal_capacity *= 2; animals = realloc(animals, animal_capacity * sizeof(Animal*)); if (!animals) { perror("realloc failed"); exit(1); } } // 分配单个Animal内存 Animal* new_animal = malloc(sizeof(Animal)); if (!new_animal) { perror("malloc failed"); exit(1); } // 解析名称和数值 char name[50]; int value; sscanf(input, "%s %d", name, &value); new_animal->name = malloc(strlen(name) + 1); strcpy(new_animal->name, name); new_animal->value = value; // 初始化子项结构 new_animal->children = malloc(INIT_CAPACITY * sizeof(Animal*)); new_animal->child_count = 0; // 读取子项(约定子项输入前加缩进,直到输入非缩进行) while (fgets(input, sizeof(input), stdin) != NULL) { if (input[0] != ' ') { ungetc(input[0], stdin); // 把非子项内容放回输入流 break; } // 解析子项 char child_name[50]; int child_value; sscanf(input, " %s %d", child_name, &child_value); // 扩容子项数组 if (new_animal->child_count >= INIT_CAPACITY) { int new_cap = new_animal->child_count * 2; new_animal->children = realloc(new_animal->children, new_cap * sizeof(Animal*)); if (!new_animal->children) { perror("realloc failed"); exit(1); } } Animal* child = malloc(sizeof(Animal)); child->name = malloc(strlen(child_name) + 1); strcpy(child->name, child_name); child->value = child_value; child->children = NULL; // 子项若无需再嵌套可设为NULL,否则同理初始化 child->child_count = 0; new_animal->children[new_animal->child_count++] = child; } animals[animal_count++] = new_animal; }
- 子项的动态管理
和父项逻辑一致,每个Animal的children指针数组可以通过realloc随时扩容,child_count记录当前子项数量,确保不会越界。
三、按数值排序输出
可以用标准库的qsort函数实现排序,自定义比较函数即可:
// 按数值升序排序的比较函数 int compare_animal(const void* a, const void* b) { Animal* animal_a = *(Animal**)a; Animal* animal_b = *(Animal**)b; return animal_a->value - animal_b->value; } // 排序并输出 qsort(animals, animal_count, sizeof(Animal*), compare_animal); printf("按数值排序的父项:\n"); for (int i = 0; i < animal_count; i++) { printf("%s: %d\n", animals[i]->name, animals[i]->value); // 子项同样排序输出 qsort(animals[i]->children, animals[i]->child_count, sizeof(Animal*), compare_animal); printf(" 子项:\n"); for (int j = 0; j < animals[i]->child_count; j++) { printf(" %s: %d\n", animals[i]->children[j]->name, animals[i]->children[j]->value); } }
四、注意事项
- 程序结束时要递归释放所有动态分配的内存,避免内存泄漏。
- 输入解析逻辑可以根据实际需求调整(比如增加格式校验、支持多层嵌套等)。
内容的提问来源于stack exchange,提问作者João Coelho
相关产品推荐
相关产品推荐

