面试题答案
一键面试链表结构定义
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
typedef struct ListNode {
int data;
struct ListNode* next;
} ListNode;
排序函数实现
// 交换两个节点的数据
void swap(ListNode* a, ListNode* b) {
int temp = a->data;
a->data = b->data;
b->data = temp;
}
// 对链表进行冒泡排序
void sortList(ListNode* head) {
if (head == NULL) return;
ListNode* ptr1, * ptr2;
for (ptr1 = head; ptr1 != NULL; ptr1 = ptr1->next) {
for (ptr2 = ptr1->next; ptr2 != NULL; ptr2 = ptr2->next) {
if (ptr1->data > ptr2->data) {
swap(ptr1, ptr2);
}
}
}
}
内存管理说明
在链表的操作过程中,注意创建节点时使用 malloc
分配内存,使用完毕后要使用 free
释放内存,以避免内存泄漏。例如,创建新节点时:
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
if (newNode == NULL) {
// 处理内存分配失败的情况
return;
}
// 使用完节点后释放内存
free(newNode);
结构体指针访问成员的优势
- 内存布局方面:
- 链表这种复杂数据结构通常在堆上动态分配内存。使用结构体指针可以灵活地控制内存的分配和释放,节点在内存中不必连续存储。如果使用直接结构体变量,在链表场景下很难动态地添加或删除节点,因为直接变量的内存位置是固定的,不利于链表这种动态数据结构的内存布局。
- 程序运行效率方面:
- 结构体指针在访问成员时,通过指针直接寻址,对于链表这种需要频繁遍历节点的场景,效率较高。而直接结构体变量在链表中使用时,若要移动到下一个节点,可能需要进行更多的数据拷贝操作(例如将整个结构体变量移动到新位置等复杂操作),相比之下效率较低。
- 可维护性方面:
- 结构体指针使得代码更具模块化和可读性。例如在链表的插入、删除操作中,通过指针操作节点非常直观和清晰。如果使用直接结构体变量,代码将变得复杂且难以理解,特别是在涉及到节点关系的调整时,直接变量不利于表达节点间的逻辑关系,使得代码的可维护性降低。