一(3)理解 newNode->next = head 和 Node* temp = head 的区别
1. 指针变量的本质:存储内存地址
在 C 语言中,指针变量(如 head、temp、newNode->next)的本质是存储内存地址的变量。它们的值是一个“地址编号”(比如 0x1000、0x2000),表示它们指向的内存位置。
Node* head = NULL; // head 存储的地址是 NULL(0x0)
Node* temp; // temp 未初始化(存储随机地址)当执行 Node* temp = head; 时:
temp被赋值为head的当前值(即NULL)。- 此时
temp和head存储的地址相同(都是0x0),但它们是 两个不同的指针变量(内存中占用不同的空间)。
2. 链表节点的结构:数据 + 指针
单链表的每个节点(struct Node)包含两部分:
- 数据域(
data):存储实际数据(如int类型的值)。 - 指针域(
next):存储 下一个节点的内存地址(类型是Node*)。
例如,一个节点 A 的结构可能如下:
节点 A 的内存地址:0x1000
节点 A 的 data 域:存储值 10(假设是 int 类型)
节点 A 的 next 域:存储下一个节点 B 的地址 0x2000
此时,head 指针变量存储的地址是 0x1000(指向节点 A),因此 head 被称为“头指针”(指向链表的第一个节点)。
3. Node* temp = head 的含义:复制头指针的地址
Node* temp = head; 这行代码的作用是:
让临时指针 temp 存储头指针 head 当前的地址值(即 temp 和 head 指向同一个内存位置)。
示例:
假设原链表头指针 head 存储的地址是 0x1000(指向节点 A):
Node* head = (Node*)0x1000; // head 指向节点 A(地址 0x1000)
Node* temp = head; // temp 存储的地址也是 0x1000(和 head 相同)此时:
head和temp是两个不同的指针变量(内存中占用不同空间)。- 但它们的值相同(都是
0x1000),因此都指向节点 A。
4. newNode->next = head 的含义:连接新节点到原链表头部
newNode->next = head 这行代码的作用是:
将新节点 newNode 的 next 指针域(存储下一个节点地址的位置)设置为头指针 head 当前的地址值(即让新节点的下一个节点是原链表的头节点)。
示例:
假设我们要插入新节点 X(地址 0x3000),原链表头指针 head 存储的地址是 0x1000(指向节点 A):
Node* newNode = (Node*)0x3000; // 新节点 X 的地址是 0x3000
newNode->data = 20; // X 的数据域存储 20
newNode->next = head; // X 的 next 域设置为 head 的值(0x1000)此时:
- 新节点
X的next域存储的地址是0x1000(指向原头节点 A)。 - 因此,
X的下一个节点是A,链表结构变为:X → A → ...。
5. 头插法的完整逻辑:移动头指针
头插法的最终目标是将新节点 X 变为链表的新头节点。因此,在 newNode->next = head 之后,需要更新头指针 head 的值为新节点 X 的地址。
示例:
void insertAtHead(int data) {Node* newNode = createNode(data); // 创建新节点 X(地址 0x3000)newNode->next = head; // X 的 next 指向原头节点 A(地址 0x1000)head = newNode; // 头指针更新为 X 的地址(0x3000)
}执行后:
- 头指针
head存储的地址变为0x3000(指向新节点 X)。 - 链表结构变为:
head → X → A → ...(X 是新的头节点)。
6. 关键总结:指针的“指向”是地址的复制
-
Node* temp = head:temp复制了head的地址值(两者指向同一个节点)。-
newNode->next = head:newNode的next域复制了head的地址值(新节点的下一个节点是原头节点)。-
head = newNode:head复制了newNode的地址值(头指针指向新节点,新节点成为新头)。
用图示更直观理解
假设原链表结构为:
head(地址 0x4000) → A(地址 0x1000,data=10) → B(地址 0x2000,data=20) → NULL
步骤 1:创建新节点 X
Node* newNode = createNode(30); // X 的地址是 0x3000,next 初始化为 NULL此时内存结构:
head → 0x4000 → A → 0x1000 → B → 0x2000 → NULL newNode → 0x3000 → next → NULL
步骤 2:执行 newNode->next = head
head 的值是 0x4000(指向 A),因此 newNode->next 被设置为 0x4000。
此时内存结构:
newNode → 0x3000 → next → 0x4000(指向 A)
步骤 3:执行 head = newNode
head 被更新为 0x3000(指向 X)。
最终链表结构:
head → 0x3000 → X(data=30) → next → 0x4000 → A(data=10) → next → 0x2000 → B(data=20) → NULL
总结
-
Node* temp = head:临时指针temp复制头指针head的地址,用于后续操作(如遍历或删除头节点时保留原头节点)。 -
newNode->next = head*:新节点的next指针复制头指针head的地址,使新节点连接到原链表的头部位置。 -
head = newNode:头指针更新为新节点的地址,使新节点成为链表的新头节点。
