如果我在最初的后方移动一组节点,我需要帮助更新圆形链表的后部。
让我们假设后方是后方节点,后方是后方节点,后面循环回[1]
。
[1][2][3][4][5]
<-------------/
如果我在节点[1][2][3]
之后移动[5]
[4][5][1][2][3]
,打破了循环链表,
如何将[3]
更新为后方和后方。下一页指向[1]
?
答案 0 :(得分:0)
由于链接集的性质是圆形,因此您必须在移动后断开链接并重新建立链接。这里的重要链接是那些将被“破坏”的链接,即(如果它是单链表,正如我所假设的那样),[3] -> [4]
的链接和[5] -> [1]
的链接
您的列表中有两个部分,[1][2][3]
,我们可以调用A
,[4][5]
,我们可以调用B
。下面显示的-->
链接是指向列表中第一个元素的指针。
--> A -> B -+
^ |
| |
+-------+
您要做的是重置链接,以便A
中的最后一个元素指向B
中的第一个元素,B
中的最后一个元素指向第一个元素在A
。此外,列表的开头现在是B中的第一个元素。
--> B -> A -+
^ |
| |
+-------+
现在我们只需要打破并重置需要它们的链接。
--> [1][2][3] -> [4][5] -+ --> [4][5] -> [1][2][3] -+
^ | => ^ |
+-------------------+ +-------------------+
B
的第一个元素,即[4]
B
中的最后一个元素[5]
设置为指向A
中的第一个元素,即[1]
。这种情况已经按照这种方式设置,但不要依赖于此。 :)A
中的最后一个元素[3]
设置为指向B
中的第一个元素,即[4]
。如您所见,我们真正关心的唯一节点是列表每个部分的第一个和最后一个元素,即A
和B
的开始和结束元素。在这种情况下,其中一个部分也包含第一个元素,因此我们必须移动哪个元素是“第一个”元素的概念。希望这会有所帮助。
答案 1 :(得分:0)
这是家庭作业吗?
你是如何做“移动”的?
我会把它变成一个函数,比如list.move(first, last, after)
,在这种情况下会list.move(1, 3, 5)
。
你有跟踪列表前/后和尾/尾的变量。我假设他们被称为list.front
和list.rear
。
所以在每种情况下,你都想这样做:
list[after].next = list[first]
然后我可以看到两个特殊情况:
list[after] == list.rear
)list[start] == list.front
)因此,您可以使用if
语句处理这些语句。
答案 2 :(得分:0)
我认为这回答了它(如果我理解正确的话)
Node insertAtRear(Node rear, T value) {
Node tmp = new Node(value);
if(rear!=null) {
tmp.next = rear.next;
rear.next = tmp
rear = tmp
} else {
// this is probably the first element to be inserted
rear = tmp;
rear.next = rear;
}
}
答案 3 :(得分:0)
在[1] [2] [3] [4] [5]开始的基础上工作,你想最终得到[4] [5] [1] [2] [3]你可以使用指针执行此操作,而不是更改数据结构。
正如你所指出的那样,我们有一个循环列表,其中指针“rear.next”指向第一个桶,每个后续桶都有一个.next指针将它链接到它的最右边的邻居,直到我们再次回到后桶。基本上是一堆桶相互连接。
如果我们创建“tail”节点和“header”节点,我们可以使用它们来排序列表。这些是标记,而不是圆圈的一部分,只是指向起点或终点。
所以为了得到[1] [2] [3] [4] [5]我们可以设置尾节点指向[5]然后按照[5]的下一个指针引导我们到[1]我们将我们的标题设置为指向。所以header = [1]; tail = [5]
从标题开始并按照下一个指针操作列表,每次我们可以按此顺序访问我们的项目[1] [2] [3] [4] [5]。不出意外!
让我们改变,尽管我们希望[3]成为后方。所以让我们设置我们的尾节点指向[3]。然后按照[3]的下一个指针到达[4]。为此我们分配了header.So header = [4]; tail = [3]
现在通过我们的列表开始,无论我们的标题点是什么[4] [5] [1] [2] [3]。
看来我们已经执行了移动操作,但我们没有篡改我们的数据结构或其链接 - 只是我们使用它的方式。我们改变的只是我们的标题和尾巴。 (我们的指示)。这就是圆形清单的美丽。