将链表拆分为两个列表,并将它们的节点交织在一起成为一个链表

时间:2014-02-14 18:45:42

标签: java nodes

我正在尝试将节点列表拆分为两个,并将两个链接列表合并回一个列表中。例如,{"KH","4C","8C","QC","3D","7D","JD"}变为{"KH","4C","8C","QC"} {"3D","7D","JD"}(如果在这种情况下,列表具有奇数个节点,则第一个列表更长)并返回列表{"KH","3D","4C","7D","8C","JD","QC"}。看看我的错误,似乎我没有在if语句中正确地合并列表。

我必须使用提供的节点类,不能使用静态变量,数组或Java集合。你能解释我应该如何将我的两个节点列表合并在一起吗?

我的代码

public class ListShuffleExample {

public static Node<String> shuffle(Node<String> deck) {
    if(deck == null){
        return null;
    }
    int decklength = length(deck);
    if(decklength % 2 == 0){
        Node<String> first = deck;
        Node<String> second = deck;
        int halflength = decklength / 2;
        int i;
        for(i = 0; i < halflength; i++){
            second = second.next;
        }
        while(second.next != null){
            first.next = second;
            second = second.next;
        }

        return first;

    }
    else{
        Node<String> first = deck;
        Node<String> second = deck;
        int halflength = (decklength / 2) + 1;
        int i;
        for(i = 0; i < halflength; i++){
            second = second.next;
        }
        while(second.next != null){
            first.next = second;
            second = second.next;
        }

        return first;

    }

}

public static int length(Node<String> adeck){
    int length = 0;

    while(adeck.next != null){
        length++;
        adeck = adeck.next;
    }

    return length;
}
}

节点类

public final class Node<T> {
public final T       value;
public       Node<T> next;

public Node(T _value) {
    this( _value, null );
}
public Node(T _value, Node<T> _next) {
    value = _value;
    next  = _next;
}
@Override
public String toString() {
    return "" + value;
}
}

我的测试用例

@Test
public void testMany() {
    @SuppressWarnings("unchecked")
    Node<String> input  = makeList( _AH, _5H, _9H, _KH, _4C, _8C, _QC, _3D, _7D, _JD, _2S, _6S, _TS );
    Node<String> actual = ListShuffleExample.shuffle( input );
//                                           _AH,      _5H,      _9H,      _KH,      _4C,      _8C,      _QC
//                                                _3D,      _7D,      _JD,      _2S,      _6S,      _TS
    for (Object expected : new Object[]{ _AH, _3D, _5H, _7D, _9H, _JD, _KH, _2S, _4C, _6S, _8C, _TS, _QC }) {
        assertEquals( "Incorrect value", expected, actual );
        actual = actual.next;
    }
    assertNull( "Incorrect result", actual );
}

1 个答案:

答案 0 :(得分:0)

根据我的理解,你并没有真正改变,但是你将两个列表交织在一起。因此,当你到达卡片组并将它们连接到一个卡座中时,就像它们从每个卡座中交替一样。

您的代码中存在问题:

  while(second.next != null){
            first.next = second;
            second = second.next;
        }

您永远不会更新first引用以移动到下一个节点,并且您永远不会更新second引用以指向第一个之后的引用。您总是会覆盖相同的first.next

怎么样:

 Node<String> curFirst = first;
 Node<String> curSecond = second;

 while(curFirst != null && curSecond != null)
 {
    //save the next one of the first list
    Node<String> nextFirst = curFirst.next;

    //set the next one of the first list to the first one of the second list
    curFirst.next = curSecond;

    //save the next one of the second list
    Node<String> nextSecond = curSecond.next;

    //set the next one after the inserted item to the previous next of the first list
    curSecond.next = nextFirst;

    //set the current references to the next ones
    curFirst = nextFirst;
    curSecond = nextSecond;
 }
 //once any of the pointers becomes null it means we're done because the rest of the list should be still intact

当列表为空,或者列表中只有1个项目等时,您可能需要检查一些极端情况,但我留给您!

更新以下评论后

长度计算也是错误的,如果列表为空(例如NullPointerExceptionaDeck),它将抛出null,如果它包含任何项目,将返回少一项。您应该将条件更改为while(adeck != null)

此外,没有重复的代码。将您正在遍历的部分移动到halflength并将其合并到else之后。当长度均匀或奇数时,它都是相同的。