交换循环链表节点

时间:2011-02-11 06:22:06

标签: java

基本上我必须将循环链表中的一组节点移动到同一链表中的不同位置。

      prev  ptr

[1] - > [2] - > [3] - > [4]
< --------------------
假设我想在3和4之间移动1和2,并将4圈转回3。 我有临时指针指向1(temp1),3(temp3)和4(temp4)。 我认为这些是操纵的重要指针,所以我为它们设置临时值。

如何设置prev和ptr指针以与temp指针协调? 这非常令人困惑,我把它放在一起并尝试打印列表的任何组合, 它会让我陷入无限循环。我想了解一种接近的精确方法 这个。谢谢。

2 个答案:

答案 0 :(得分:1)

将操作视为两个不同的操作可能更容易。删除,然后插入。

// remove the node
Node node = ...; // whatever identifies the node to operate on
prev(node).setNext(next(node));

// insert it into its new position
Node newPrev = ...; // whatever identifies the node to operate on
Node newNext = newPrev.next();
newPrev.setNext(node);
node.setNext(newNext);

答案 1 :(得分:0)

请注意,enonu的方法在某些特殊情况下不起作用,例如,如果其中一个节点紧挨着另一个节点,或两者都引用同一节点。

以下方法通过观察P B ,A的前身和 B ,B的后继,交换两个节点A和B.首先,我们删除A和B,然后我们插入S B 的左边,最后插入P A 的右边。在A是B的后继者的特殊情况下,我们使用交换参数重新启动。如果两者都是彼此的继承者,我们什么都不做。

private void swap(Node a, Node b) {
    if (a.pred == b) {
        if (b.pred != a)
            swap(b, a);

         return;
    }

    Node pa = a.pred, sb = b.succ;

    // remove a from list
    pa.succ = a.succ;
    pa.succ.pred = pa;

    // remove b from list
    sb.pred = b.pred;
    sb.pred.succ = sb;

    // add a before sb
    a.pred = sb.pred;
    a.succ = sb;
    a.pred.succ = a;
    a.succ.pred = a;

    // add b after pa
    b.succ = pa.succ;
    b.pred = pa;
    b.pred.succ = b;
    b.succ.pred = b;
}