我明天要考试数据结构,我想弄清楚这段代码中的Insert函数。请你在函数Insert
中向我解释为什么是temp->next = head
?
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Node* head;
void Insert(int x) {
struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = x;
temp->next = NULL;
if(head != NULL) { temp->next = head;}
head = temp;
}
void Print() {
struct Node* temp = head;
printf("List is: ");
while(temp != NULL) {
printf(" %d",temp->data);
temp = temp->next;
}
printf("n");
}
int main() {
head = NULL;
Insert(1);
Insert(2);
Insert(3);
Insert(4);
Insert(5);
Print();
return 0;
}
根据您的评论-
"但是当我们删除这个部分时,为什么程序不起作用?是吗?"将旧负责人的地址保留到打印列表中?
不,不是。因为在这里。。。
if(head != NULL) { temp->next = head;}
head = temp;
我们看到,如果我们删除head = temp;
,您将孤立您的列表,因为如果是head == NULL
,它仍然是NULL
。如果没有,你就没有链接到temp
,所以你孤立了temp
和所有其他insert
。
if(head != NULL) { temp->next = head;}
语句确保,如果您确实有一个,则您的列表会附加到新的head
,但如果没有head = temp;
语句,则无关紧要。
void Insert(int x) {
struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = x;
temp->next = NULL;
if(head != NULL) { temp->next = head;}
head = temp;
}
让我们看看例子:-
insert(1);
将创建新节点并将其数据字段设置为1。则它检查head是否为NULL。是的,因为这是我们插入的第一个元素。所以它指向这个元素。这意味着在这次之后
head -> 1
现在你做
insert(2);
在同一行上,它将创建一个节点来容纳2。接下来,它检查head是否为NULL。它不是那么执行
temp->next = head;
意味着temp节点的(它是2)下一个将指向头(它现在是1)。在该声明之后
2 -> 1 (head)
然后你执行
head = temp;
这将使头指向2(新创建的节点)
(head) 2->1
通过这种方式,您将继续添加元素,并保持头指针指向添加到列表中的最新元素。这将帮助您稍后使用头指针遍历列表。
通过替换头在列表的前面插入新节点。新头将是新分配的节点temp
,而旧头将是列表中的第二个节点,因此是temp->next
。
这些概念可以在纸和笔的帮助下很容易地想出来。或者使用ASCII草图,其中->
表示通过next
指针的链接,|
表示指向非节点链接的节点的直接指针:
head
|
3 -> 2 -> 1 -> NULL
插入4之后,但在分配新磁头之前:
temp head
| |
4 -> 3 -> 2 -> 1 -> NULL
分配新磁头后:
head
|
4 -> 3 -> 2 -> 1 -> NULL
现在您有了一个合适的列表,可以通过head
和next
指针访问所有添加的节点。如果没有对head
进行配置,则只能访问旧节点。
这也适用于head == NULL
的空列表,除非您不能访问head->next
。
在链接列表中添加新元素后会发生这种情况。当您添加新元素时,您必须使新元素成为头,因此您必须指向上一个头作为链表中的下一个项目。