合并两个有序的单链表,合并后仍然有序
思考
- 合并两个链表应该将一个为主链一个为辅链,在主链上添加辅链的节点
方法:
- 先自己定义出主辅链
- 主链应该比辅链长
- 将主链为外循环,辅链为内循环
- 外循环每动一次就对应主链的节点移动一个位置这个节点和辅链的所有节点相比较
- 内循环每动一次就对应辅链的节点移动一个为位置和相应的节点和主链此时的节点比较
- 注意:链表中数据转移的循环不同于以往的循环
- 辅链转移后的节点无法遍历到;主链得到的节点不应该再使用
- 因为这个问题是有序的,所以,不存在后面的节点比前面的节点小,所以只需要循环一遍
注意点:
- 两条链表都为空
- 一条为空,一条不为空
- 辅链转移到主链的节点,可能会导致你的判断出错
- 当主链遍历完,辅链还有数据
代码:
public static SingleLinkedList consolidatedList(animalNode head1, animalNode head2) {
/*方法:
* 1.将一个链表为主,另一个链表为辅
* 2.为辅的链表遍历取出节点,添加到主链表中*/
/*注意:
* 1.两个链表都为空
* 2.一个链表为空,一个不为空
* - 不为空的直接返回
* 3.当主链遍历完,辅链还有直接接上主链
* 4.(有点小用)节点数多的为主,节点数少的为辅*/
animalNode resultNode = new animalNode(0, "", "");//头节点,
SingleLinkedList resultList = new SingleLinkedList();//链表
//两个都为空
if (head1.next == null && head2.next == null) {
return resultList;
}
//一个为空,另一个不为空
if (head1.next == null && head2.next != null) {
resultNode.next = head2.next;
resultList.setHead(resultNode);
return resultList;
}
if (head2.next == null && head1.next != null) {
resultNode.next = head1.next;
resultList.setHead(resultNode);
return resultList;
}
int length1 = getLength(head1);
int length2 = getLength(head2);
int m = length1 - length2;
animalNode cur1;//主链的移动节点
animalNode cur2;//辅链的移动节点
//判断那个链表长
if(m>=0){//head1长
resultNode.next=head1.next;
cur1 = resultNode;//主链的移动节点从头节点开始,为添加方便
cur2 = head2.next;//辅链的移动节点从第一个节点开始,为转移方便
}
else {//head2长
resultNode.next=head2.next;
cur1=resultNode;
cur2=head1.next;
}
boolean flag = false;//是否进行了转移
while (cur1.next != null) {
animalNode temp1 = cur1;//temp1为储存cur1的数据
cur1 = cur1.next;//移动主链节点
/* 注意:
如果出现连续的辅链的节点小于当前要比较的主链的节点,那么下一次while循环,temp1.next为你刚刚添加的节点
需要在判断转移的节点的是否转移,若转移了,那temp1应该要指向下一个节点,在while前*/
while (cur2 != null&&cur2.id <= temp1.next.id) {
animalNode temp2 = cur2;//temp2为存储cur2的数据
cur2 = cur2.next;//移动辅链节点
temp2.next = temp1.next;
temp1.next = temp2;//转移辅链节点到主链上
flag = true;
if (flag) {//若进行了转移就将temp1后移一个节点,temp1.next保持为原先的节点
temp1 = temp1.next;
flag = false;
}
}
}
if (cur2 != null) {//如果主链遍历完了,辅链还有数据就将辅链的节点都转移到主链的最后一个节点后
cur1.next = cur2;
}
resultList.setHead(resultNode);//将头节点存入链表中
return resultList;
}
对于链表的正逆序问题
- 可以加入一下代码:
//判断是正序递增还是逆序递减的链表
boolean xun= head1.next.id <= head1.next.next.id;//true为正序,false为逆序
在内循环前加入对于xun的判断就行
2. 一正一逆
- 或者你可以将长的作为标准,短的先进行反转,再循环