MST
星途 面试题库

面试题:C语言结构体嵌套在复杂数据结构设计中的应用

设计一个基于结构体嵌套的图数据结构,图中的每个节点可以包含任意数量的子节点,且节点本身具有一些属性(如节点编号、节点名称等)。请使用C语言完成结构体的设计,以及实现添加节点、删除节点、遍历图等基本操作的函数框架,并说明在这种结构体嵌套设计下,如何高效地管理内存和避免内存泄漏。
21.8万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义节点属性结构体
typedef struct NodeAttributes {
    int id;
    char name[50];
} NodeAttributes;

// 定义图节点结构体
typedef struct GraphNode {
    NodeAttributes attributes;
    struct GraphNode** children;
    int childCount;
    int capacity;
} GraphNode;

// 定义图结构体
typedef struct Graph {
    GraphNode* root;
} Graph;

// 创建新节点
GraphNode* createNode(int id, const char* name) {
    GraphNode* newNode = (GraphNode*)malloc(sizeof(GraphNode));
    newNode->attributes.id = id;
    strcpy(newNode->attributes.name, name);
    newNode->childCount = 0;
    newNode->capacity = 10; // 初始容量
    newNode->children = (GraphNode**)malloc(newNode->capacity * sizeof(GraphNode*));
    return newNode;
}

// 添加子节点
void addChild(GraphNode* parent, GraphNode* child) {
    if (parent->childCount >= parent->capacity) {
        parent->capacity *= 2;
        parent->children = (GraphNode**)realloc(parent->children, parent->capacity * sizeof(GraphNode*));
    }
    parent->children[parent->childCount++] = child;
}

// 删除节点及其子节点(递归)
void deleteNode(GraphNode* node) {
    if (node == NULL) return;
    for (int i = 0; i < node->childCount; i++) {
        deleteNode(node->children[i]);
    }
    free(node->children);
    free(node);
}

// 前序遍历图(递归)
void preOrderTraversal(GraphNode* node) {
    if (node == NULL) return;
    printf("Node ID: %d, Name: %s\n", node->attributes.id, node->attributes.name);
    for (int i = 0; i < node->childCount; i++) {
        preOrderTraversal(node->children[i]);
    }
}

// 初始化图
Graph* createGraph() {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->root = NULL;
    return graph;
}

// 释放图内存
void freeGraph(Graph* graph) {
    if (graph == NULL) return;
    deleteNode(graph->root);
    free(graph);
}

在这种结构体嵌套设计下管理内存和避免内存泄漏的方法:

  1. 节点创建与释放:在创建节点时,使用malloc分配内存,在删除节点时,递归地释放所有子节点的内存,然后释放当前节点本身及其子节点数组的内存。例如deleteNode函数,先递归删除子节点,再释放children数组和节点自身内存。
  2. 动态内存调整:在添加子节点时,如果当前子节点数组已满,使用realloc重新分配更大的内存空间,避免内存溢出。如addChild函数,当childCount达到capacity时,将capacity翻倍并重新分配内存。
  3. 图的整体管理:在创建图时,为图结构体分配内存,在释放图时,先释放根节点及其所有子节点,再释放图结构体本身。如createGraphfreeGraph函数。