给定两个单链表 L1=a1→a2→⋯→an−1→an 和 L2=b1→b2→⋯→bm−1→bm。如果 n≥2m,你的任务是将比较短的那个链表逆序,然后将之并入比较长的那个链表,得到一个形如 a1→a2→bm→a3→a4→bm−1⋯ 的结果。例如给定两个链表分别为 6→7 和 1→2→3→4→5,你应该输出 1→2→7→3→4→6→5。
输入格式:
输入首先在第一行中给出两个链表 L1 和 L2 的头结点的地址,以及正整数
N (≤105),即给定的结点总数。一个结点的地址是一个 5 位数的非负整数,空地址 NULL 用 -1
表示。
随后 N 行,每行按以下格式给出一个结点的信息:
Address Data Next
其中 Address
是结点的地址,Data
是不超过 105 的正整数,Next
是下一个结点的地址。题目保证没有空链表,并且较长的链表至少是较短链表的两倍长。
输出格式:
按顺序输出结果链表,每个结点占一行,格式与输入相同。
输入样例:
00100 01000 7
02233 2 34891
00100 6 00001
34891 3 10086
01000 1 02233
00033 5 -1
10086 4 00033
00001 7 -1
输出样例:
01000 1 02233
02233 2 00001
00001 7 34891
34891 3 10086
10086 4 00100
00100 6 00033
00033 5 -1
这个题目所述的链表是给定了地址的,不太好用链表去实现,只能用数组来模拟。
感觉我的做法有点复杂,关键是合并链表的地方,可以参考一下思路,有图。
#include<cstdio>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
//定义双向链表节点
struct Node{
int pre;
int num;
int now; //当前节点地址
int next;
};
void print(Node node);
Node nodes[100005];
Node L1,L2,preNode;
int main(){
int head1,head2,N;
int tail1,tail2;
int length1=0,length2=0;
int nowAddress=0,nextAddress=0;
cin>>head1>>head2>>N;
int Address,Data,Next;
while(N--){
cin>>Address>>Data>>Next;
nodes[Address].num = Data;
nodes[Address].next = Next;
nodes[Address].now = Address;
nodes[Next].pre = Address;
}
//头结点的前一个为空
nodes[head1].pre = -1;
L1 = nodes[head1];
//分别从头结点遍历两个链表 计算长度
while(L1.next != -1){
nextAddress = L1.next;
L1 = nodes[nextAddress];
length1++;
}
//记录尾节点地址
tail1 = nextAddress;
nodes[head2].pre = -1;
L2 = nodes[head2];
while(L2.next != -1){
nextAddress = L2.next;
L2 = nodes[L2.next];
length2++;
}
tail2 = nextAddress;
int times = 1;
int tempL1,tempL2;
bool end = false;
//如果B链更长,则互换,保证A链始终是最长的
if(length2>length1){
swap(L1,L2);
swap(head1,head2);
swap(tail1,tail2);
}
L1 = nodes[head1];
L2 = nodes[tail2];
while(1){
//A链表2个节点 且 B 链条还有节点 end说明没节点了
if(times==2 && !end){
//1.记录当前L1的下一个节点,用作下次循环的头节点
tempL2 = L2.pre ;
//2.改变L2指向
nodes[L2.now].next = L1.next;
//3.改变L1指向
nodes[L1.now].next = L2.now;
//判断链表是否已经结束条件
if(L2.pre == -1){
end = true;
}
//4.L2向后移1个节点
L1 = nodes[L2.now];
//5.L1向前移1个节点
L2 = nodes[tempL2];
//清空次数
times = 0;
}else{
//循环结束条件 L1链表结束则结束
if(L1.next == -1){
break;
}
L1=nodes[L1.next];
//次数加一
times++;
}
}
//输出
L1 = nodes[head1];
while(1){
print(L1);
if(L1.next == -1)
break;
L1 = nodes[L1.next];
}
return 0;
}
//打印
void print(Node node){
if(node.next!=-1){
cout<<setw(5) << setfill('0') <<node.now<<" "<<node.num<<" "<<setw(5) << setfill('0') <<node.next<<endl;
}
else{
cout<<setw(5) << setfill('0') <<node.now<<" "<<node.num<<" "<<node.next<<endl;
}
}