[英]Move node to beginning of singly linked list
In Pascal, when I have a singly linked list with nodes defined like this, 在Pascal中,当我有一个单独的链接列表,节点定义如下,
pNode = ^Node;
Node = record
data : data;
next : pNode;
end;
and when I iterate through the list like this 当我像这样迭代列表
while y<>z do begin
if y^.data < x^.data then begin
{ HERE I WOULD LIKE TO MOVE y IN FRONT OF X }
end;
y:=y^.next;
end;
where x is the pivot (beginning of the list), y is the 'index', z is the tail (the end) of the list (yes, I am trying to perform a quicksort on a singly linked list). 其中x是枢轴(列表的开头),y是'索引',z是列表的尾部(结束)(是的,我试图在单链表上执行快速排序)。 How would I accomplish the task in the comment?
我如何完成评论中的任务?
I made the procedure insertAfter
: 我做了程序
insertAfter
:
procedure List.insertAfter(n : pNode; var what : data);
var newn : pNode;
begin
new(newn);
newn^.data := what;
newn^.next := n^.next;
n^.next := newn;
end;
and insertInstead
和
insertInstead
procedure List.insertInstead(n : pNode; var what : data);
begin
List.insterAfter(n, n^.data);
n^.data:=what;
end;
and similarly deleteAfter(n : pNode)
并类似
deleteAfter(n : pNode)
procedure List.deleteAfter(n : pNode);
var q : pNode;
begin
q := n^.next;
n^.next := n^.next^.next;
dispose(q);
end;
and delete(n : pNode)
并
delete(n : pNode)
procedure List.delete(n : pNode);
begin
if n^.next <> tail then begin
n^.data := n^.next^.data;
deleteAfter(n);
end
else begin
dispose(tail);
tail:=n;
tail^.next := nil;
end;
end;
Now when I put in the iteration, instead of the comment 现在,当我放入迭代时,而不是评论
list.insertInstead(x,y^.data);
list.delete(y);
, it doesn't work, presumably because y^.next
now doesn't point to the same node as before the move. ,它不起作用,大概是因为
y^.next
现在不指向移动前的同一节点。
So the question is: how do I move the node to the beginning with y^.next
still pointing to the same node? 所以问题是:如何将节点移动到开头,
y^.next
仍然指向同一个节点?
PS.: I have tried the obvious: using and auxiliary variable to store the actual value of y before the move, but it seems to change along with y. PS。:我已经尝试过显而易见的:使用和辅助变量来存储移动前y的实际值,但它似乎随y一起变化。
Here is the original code: Stack , List , Quicksort . 这是原始代码: Stack , List , Quicksort 。
Maybe the easiest way is only to change (swap) the values of the nodes. 也许最简单的方法是改变(交换)节点的值。
{ HERE I WOULD LIKE TO MOVE y IN FRONT OF X }
tmp := x^.data
x^.data := y^.data
y^data := tmp
UPDATE: Here is the similar answer: https://stackoverflow.com/a/1536046/2490538 更新:以下是类似的答案: https : //stackoverflow.com/a/1536046/2490538
Zdravím. Zdravím。
I think I might see the problem. 我想我可能会看到这个问题。 The first line of your insert code
插入代码的第一行
list.insertInstead(x,y^.data);
works fine. 工作正常。 It puts a new node immediately after x and populates it with y's data (so you effectively now have a copy of node y after node x.
它在x之后立即放置一个新节点并用y的数据填充它(所以你现在有效地在节点x之后有一个节点y的副本。
But I don't think the second line 但我不认为第二行
list.delete(y);
does what you want it to. 做你想要的。 It does 'remove' the node y from the list (as you want), but does so by moving data from the node following y into y's location, and deleting that node.
它确实从列表中“删除”节点y(如您所愿),但是通过将数据从y后面的节点移动到y的位置并删除该节点来实现。 So now y.next points at the node following the node following the original y.
所以现在y.next指向原始y之后的节点之后的节点。 Maybe a diagram would help.
也许图表会有所帮助。
Before list.delete(y) 在list.delete(y)之前
node: ... - y - a - b - c - ... - z
data: ... - Y - A - B - C - ... - Z
^
y.next points here (data is A)
After list.delete(y) 在list.delete(y)之后
node: ... - y - b - c - ... - z
data: ... - A - B - C - ... - Z
^
y.next points here (data is B)
^
y points here (data is A)
so if you 'increment y as in your line 所以,如果你按照你的行增加y
y:=y^.next;
in your iteration loop you will miss out on testing data A. You can fix that by removing the y:=y^.next; 在您的迭代循环中,您将错过测试数据A.您可以通过删除y:= y ^ .next来解决这个问题。 line.
线。 But then there will still be a problem with your while loop in the line
但是你的while循环仍然会出现问题
while y<>z do begin
Because the pointer to node y doesn't change anymore (as you have removed y := y^.next), y will never equal z. 因为指向节点y的指针不再改变(因为你删除了y:= y ^ .next),y将永远不会等于z。 The simplest (but possibly not the most elegant) way to fix this might be to replace the line with
解决这个问题的最简单(但可能不是最优雅)的方法可能就是更换线路
while y^.next <>z do begin
and add a final case to test the last node. 并添加最后一个案例来测试最后一个节点。
The main loop would then look like something like (without testing): 然后主循环看起来像(没有测试):
while y^.next <> z do begin
if y^.data < x^.data then begin
list.insertInstead(x,y^.data);
list.delete(y);
end;
end;
if y^.data < x^.data then begin
list.insertInstead(x,y^.data);
list.delete(y);
end;
or, by defining a new procedure 或者,通过定义新程序
procedure list.moveiflessthan(x,y : pnode);
begin
if y^.data < x^.data then begin
list.insertInstead(x,y^.data);
list.delete(y);
end;
end;
you get 你得到
while y^.next <> z do
if y^.data < x^.data then
list.moveiflessthan(x,y);
if y^.data < x^.data then
list.moveiflessthan(x,y);
There may still be an end-case error if you reach the end of the list (I haven't checked) but I am sure you can work that out... 如果你到达列表的末尾可能仍然有一个结束错误(我没有检查),但我相信你可以解决这个问题......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.