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