这有点令人难以置信
我会尝试解释我的疑问。
例如检查这个函数:
void snoc(Lint *l, int val){
Lint i, new;
new = (Lint) malloc(sizeof(Nodo));
new->value = val;
new->next = NULL;
i=(*l);
while(i->next!=NULL){
i=i->next;
}
i->next = new;
}
我理解背后的概念并且我在使用列表时没有问题,考虑到我不能使用列表初始指针本身遍历列表(如果我这样做,我会失去初始指针的权利)
问题是,使 i=(*l)
然后使用 i=i->next 遍历列表,使 i 变量不断变化。
在这个特定的例子中,原始列表在我找到链表的末尾之前不会改变,然后我做了一个归因,瞧!我在最后插入一个元素。
我的疑问是,如果通过更改 i
,并在最后制作 i->next = new
,这是否意味着每次我制作 i=i->下一步
,改变原列表中的所有节点?
另一个例子是初始化:
void init (Lint *l){
Lint i, prev;
i=(*l);
prev=NULL;
while(i!=NULL){
if( (i->next)->next==NULL){
i->next = NULL;
}
i=i->next;
}
}
如果我这样做,最后一个元素将被删除,方法是在适当的时候将 i->next
更改为 NULL。但在此之前,我一直在通过告诉 i=i->next
i
本身进行更改
如果我要对 (*l)
本身进行此更改(通过执行 (*l)=(*l)->next
),我会破坏原始列表。
真心希望大家能理解我的疑惑。
最佳答案
是的,我们确实理解您的困惑,这是因为您没有在纸 上计算列表指针,因此您可以直观地了解正在发生的事情。在处理 node
链接问题时,请始终使用图表。例如,在您使用单链表的情况下,当前节点名为 i
(名称的可疑选择),而您的新节点名为 new
一个有用的图表是:
Singly Linked-List (non-circular)
Tail Current Head
(list start) i new
+------------+ +------------+ +------------+
| Payload | | Payload | | Payload |
+------------+ +------------+ +------------+
| Next |------->| Next |------->| Next |--->NULL
+------------+ +------------+ +------------+
现在,我打赌你可以说出什么:
changing
i
, and makingi->next = new
at the end
会做。这不是挖苦或居高临下的意思,这确实是您解决链表问题所需的方法,直到您完成足够多的工作,您可以在脑海中想象指针接线。当您进行循环或双向链表插入和删除时,这一点更为重要。无论是什么问题,如果您只是将其写下来并标记所有建立或断开的连接,您就可以在编辑器中对其进行干净的编码。
关于更改链表中的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30429036/