简体   繁体   English

将链接列表分为两个列表,并将其节点交织在一起成为一个链接列表

[英]Splitting a linked list into two lists and interleaving their nodes together into one linked list

I am attempting to split a list of nodes in two and merge the two linked lists back into a single list. 我试图将节点列表分成两个,然后将两个链接列表合并回一个列表中。 For example {"KH","4C","8C","QC","3D","7D","JD"} becomes {"KH","4C","8C","QC"} {"3D","7D","JD"} (if as in this case the lists have an odd number of nodes then the first list is longer) and returns the list {"KH","3D","4C","7D","8C","JD","QC"} . 例如{"KH","4C","8C","QC","3D","7D","JD"}变为{"KH","4C","8C","QC"} {"3D","7D","JD"} (如果在这种情况下列表的节点数为奇数,则第一个列表较长),并返回列表{"KH","3D","4C","7D","8C","JD","QC"} Looking through my errors it seems I am not merging the lists back together properly in my if statement. 查看我的错误,看来我没有在if语句中正确合并列表。

I have to use the provided node class and cannot use static variables, arrays or Java collections. 我必须使用提供的节点类,并且不能使用静态变量,数组或Java集合。 Could you explain how I should be merging my two lists of nodes back together? 您能解释一下如何将两个节点列表重新合并在一起吗?

my code 我的代码

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;
}
}

Node class 节点类

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;
}
}

my test case 我的测试用例

@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 );
}

From what I understood you are not really shuffling, but you are interleaving the two lists together. 据我了解,您并没有真正改组,但是您将两个列表交织在一起。 So its like when you get to decks of cards and join them into one deck, alternating them one from each deck. 因此,就像您进入一副纸牌并将它们合并到一个纸牌中,然后在每个纸牌中交替使用它们一样。

The problem in your code is here: 您的代码中的问题在这里:

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

You are never updating the first reference to move to the next node, and you are never updating the second reference to point to the one after the first. 您永远不会更新第first引用以移至下一个节点,也永远不会更新second引用以指向第一个引用之后的节点。 You are always overwriting the same first.next . 您总是会覆盖相同的first.next

What about: 关于什么:

 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

You might need to check for some corner cases when the list is empty, or when the list only has 1 item etc., but I leave that to you! 当列表为空或列表只有1个项目时,您可能需要检查一些特殊情况,但我留给您!

UPDATE After comments below 更新下面的评论后

The length calcuation is also wrong, it will throw a NullPointerException if the list is empty (ie aDeck is null ), and will return one less item if it contains any items. 长度计算也是错误的,如果列表为空(即aDecknull ),它将抛出NullPointerException如果包含任何项目,则返回少一个项目。 You should change the condition to while(adeck != null) . 您应该将条件更改为while(adeck != null)

Furthermore, don't have repeated code. 此外,没有重复的代码。 Move the part where you are traversing to the halflength and merging the list to after the else finishes. 将您要遍历的零件移动到halflength然后将列表合并到其他地方。 Its the same for both when the length is even or when it is odd. 当长度为偶数或为奇数时,两者都相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM