面试题答案
一键面试-
数组名与指针的关系分析:
node->data
:这里的node
是指向struct Node
结构体的指针,node->data
是结构体中名为data
的数组。数组名在大多数情况下会被隐式转换为指向其首元素的指针。所以node->data
可以当作一个int*
类型的指针,指向data
数组的第一个元素data[0]
。next
指针:struct Node *next
是链表节点中用于指向下一个节点的指针。通过这个指针,我们可以遍历整个链表。- 操作
data
数组元素的指针:如果我们要操作data
数组中的元素,可以通过node->data
转换得到的指针来进行。例如,*(node->data + i)
等价于node->data[i]
,这里i
是数组的索引。
-
链表插入、删除操作中处理数组名与指针关系,避免内存泄漏和指针错误:
- 插入操作:
- 当插入一个新节点时,需要为新节点分配内存,并正确设置新节点的
next
指针,以及data
数组中的数据。要确保新节点的next
指针指向正确的后续节点,并且不会覆盖任何现有节点的next
指针,直到新节点完全插入。
- 当插入一个新节点时,需要为新节点分配内存,并正确设置新节点的
- 删除操作:
- 当删除一个节点时,需要先保存被删除节点的
next
指针,以便后续继续遍历链表。然后释放被删除节点的内存。如果不保存next
指针,会导致链表断裂,无法继续遍历。同时,由于data
数组是结构体的一部分,释放节点内存时,data
数组占用的内存也会被正确释放,不需要额外处理。
- 当删除一个节点时,需要先保存被删除节点的
- 插入操作:
-
代码示例:
#include <stdio.h>
#include <stdlib.h>
// 定义结构体
struct Node {
int data[10];
struct Node *next;
};
// 创建新节点
struct Node* createNode(int newData[10]) {
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("内存分配失败\n");
return NULL;
}
// 将传入的新数据复制到新节点的data数组中
for (int i = 0; i < 10; i++) {
newNode->data[i] = newData[i];
}
newNode->next = NULL;
return newNode;
}
// 在链表头部插入新节点
struct Node* insertAtHead(struct Node *head, int newData[10]) {
struct Node *newNode = createNode(newData);
if (newNode == NULL) {
return head;
}
newNode->next = head;
return newNode;
}
// 删除链表头部节点
struct Node* deleteAtHead(struct Node *head) {
if (head == NULL) {
return NULL;
}
struct Node *temp = head;
head = head->next;
free(temp);
return head;
}
// 打印链表中每个节点的data数组
void printList(struct Node *head) {
struct Node *current = head;
while (current != NULL) {
printf("Node data: ");
for (int i = 0; i < 10; i++) {
printf("%d ", current->data[i]);
}
printf("\n");
current = current->next;
}
}
// 释放整个链表的内存
void freeList(struct Node *head) {
struct Node *current = head;
struct Node *nextNode;
while (current != NULL) {
nextNode = current->next;
free(current);
current = nextNode;
}
}
int main() {
struct Node *head = NULL;
int data1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int data2[10] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
head = insertAtHead(head, data1);
head = insertAtHead(head, data2);
printList(head);
head = deleteAtHead(head);
printList(head);
freeList(head);
return 0;
}
代码注释说明:
createNode
函数:- 使用
malloc
为新节点分配内存。 - 检查内存分配是否成功,如果失败,打印错误信息并返回
NULL
。 - 通过循环将传入的
newData
数组中的数据复制到新节点的data
数组中。 - 将新节点的
next
指针初始化为NULL
。
- 使用
insertAtHead
函数:- 调用
createNode
创建新节点。 - 如果新节点创建失败,返回原链表头指针。
- 将新节点的
next
指针指向原链表头节点。 - 返回新的链表头指针。
- 调用
deleteAtHead
函数:- 检查链表是否为空,如果为空,直接返回
NULL
。 - 使用临时指针
temp
保存原链表头节点。 - 将链表头指针移动到下一个节点。
- 释放原链表头节点的内存。
- 返回新的链表头指针。
- 检查链表是否为空,如果为空,直接返回
printList
函数:- 使用
current
指针遍历链表。 - 循环打印每个节点
data
数组中的元素。
- 使用
freeList
函数:- 使用
current
和nextNode
指针遍历链表并释放每个节点的内存。
- 使用