Java 将一个链表拆分为两个链表,并将它们的节点交错到一个链表中

Java 将一个链表拆分为两个链表,并将它们的节点交错到一个链表中,java,nodes,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集合。你能解释一下我应

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

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

我的代码

公共类ListShuffleExample{
公共静态节点洗牌(节点组){
if(deck==null){
返回null;
}
int decklength=长度(甲板);
如果(数据块长度%2==0){
第一节点=甲板;
节点二=甲板;
int half length=甲板长度/2;
int i;
对于(i=0;i
节点类

公共最终类节点{
公共最终T值;
公共节点下一步;
公共节点(T_值){
此(_值,null);
}
公共节点(T_值,节点_下一个){
值=_值;
下一步=_下一步;
}
@凌驾
公共字符串toString(){
返回“”+值;
}
}
我的测试用例

@测试
公共void testMany(){
@抑制警告(“未选中”)
节点输入=制造列表(_-AH、_-5H、_-9H、_-KH、_-4C、_-8C、_-QC、_-3D、_-7D、_-JD、_-2S、_-6S、_-TS);
节点实际值=ListShuffleExample.shuffle(输入);
//啊,5H,9H,KH,4C,8C,QC
//_3D、_7D、_JD、_2S、_6S、_TS
对于(预期对象:新对象[]{u-AH、\u-3D、\u-5H、\u-7D、\u-9H、\u-JD、\u-KH、\u-2S、\u-4C、\u-6S、\u-8C、\u-QC}){
assertEquals(“错误值”、预期值、实际值);
实际=实际。下一步;
}
assertNull(“结果不正确”,实际);
}

据我所知,您并不是真正在洗牌,而是将两个列表交错在一起。所以,这就像当你到达一副牌,将它们加入一副牌,从每副牌中交替一张

代码中的问题如下:

  while(second.next != null){
            first.next = second;
            second = second.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
节点curFirst=first;
节点秒=秒;
while(curFirst!=null&&curSecond!=null)
{
//保存第一个列表中的下一个
节点nextFirst=curFirst.next;
//将第一个列表的下一个设置为第二个列表的第一个
curFirst.next=curSecond;
//保存第二个列表中的下一个
节点nextSecond=curSecond.next;
//将插入项后的下一个设置为第一个列表的上一个
curSecond.next=nextFirst;
//将当前引用设置为下一个引用
curFirst=nextFirst;
curSecond=nextSecond;
}
//一旦任何指针变为null,就意味着我们完成了,因为列表的其余部分应该仍然完整
当列表为空时,或者当列表只有一个项目时,您可能需要检查一些角落案例,但我将此留给您

在下面的评论后更新

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


此外,不要重复代码。将要遍历的零件移动到
半长
,并在else完成后将列表合并到。当长度为偶数或奇数时,这两种情况都是一样的。

您是在尝试洗牌一副真正的牌吗?如果是这样的话,您应该研究一个真正的洗牌算法(这是一个好的算法),并且可能不应该有一个在洗牌后测试特定输出的测试用例。洗牌至少应该是随机的。洗牌可能是一个糟糕的词语选择。我想将节点列表一分为二,并将列表2的第一个节点放在列表1的每个节点之后。首先,您需要正确使用术语,以便我们更好地理解您。您正在实现一个链表。节点只是链表中的一个元素,它除了携带数据(一个
字符串
)外,还指向列表中的下一个元素。你有没有试着逐行调试它,看看你的参考资料是如何变化的?这是一个家庭作业问题吗?是的,这是一个家庭作业问题。所以我认为我找到原始单一列表的长度并将其拆分的方法是正确的?你刚才问到了合并的问题,这就是我主要关注的。。。顺便说一下,我还没有试过上面的代码,但是这个想法应该行得通。我想你找到长度的方式
@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 );
}
  while(second.next != null){
            first.next = second;
            second = second.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