7-51 两个有序链表序列的合并
题目
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。
输入样例:
1 3 5 -1 2 4 6 8 10 -1
结尾无空行
输出样例:
1 2 3 4 5 6 8 10
结尾无空行
查了很多资料,一些地方参考了博主们的思路。
具体思路
1.建立两个链表L1,L2,里面放着值,到-1停止。
2.初始化第三个链表L3,顺次比较L1,L2里面的值,使用L1,L2里面的结点构造出第三个链表。(因为没有说新建立一个链表把比较大小之后的值放进去,这样比较好)
3.打印L3。
代码实现
#include<iostream>
#include<malloc.h> //这个不能丢
using namespace std;
typedef struct LNode {
int data;
struct LNode* next;
}LNode, *LinkList;
//创建多个链表的方法
LinkList CreateList() //初始化和创建合在一起!
{
LinkList L = (LNode*)malloc(sizeof(LNode)); //给第一个链表创建头结点
L->next = NULL; //初始为空
LinkList p;
p = L;
int e;
while (cin >> e)
{
if (e == -1)
break; *//这里不能写成return 用return必须得返回相应值
//采用break*跳出当前循环!
//尾接法
LinkList temp = (LNode*)malloc(sizeof(LNode));
temp->data = e;
temp->next = p->next;
p->next = temp;
p = p->next;
}
return L; //循环结束再return true 不然会跳出循环 也不要忘记加
}
//合并函数
LinkList Merge(LinkList L1, LinkList L2) //整个传入
{
//初始化p3
LinkList p3;
LinkList L;
L = (LNode*)malloc(sizeof(LNode));
p3 = L;
p3->next = NULL;
LNode* p1 = L1->next; //设立指针来遍历L1,L2
LNode* p2 = L2->next;
while (p1 && p2)
{
//LinkList temp = (LNode*)malloc(sizeof(LNode));
//不太对,要求是合并,没有要求创建新的链表。
if (p1->data >= p2->data) //等于的也放进来就行!
{
p3->next = p2; //降序排列 放小的!
p2 = p2->next; //类比冒泡排序!!!
}
else {
p3->next = p1;
p1 = p1->next;
}
p3 = p3->next;
}
//其中一个遍历完之后把没有遍历完的链表的其他结点连到后面
p3->next = p1 ? p1 : p2; //三目运算符很简便,下面那段代码也可以实现,更好理解
// while (p1)
//{
// p3->next = p1;
// p1 = p1->next;
// p3 = p3->next;
//}
//while (p2)
//{
// p3->next = p2;
// p2 = p2->next;
// p3 = p3->next;
//}
L1->next = NULL; //这一步很重要!让哨头结点指向空,和两个链表断开连接
L2->next = NULL;
return L;
}
//打印L3
bool Print(LinkList &L3)
{
LNode* p = L3;
p = p->next;
if(p==NULL)
{
cout << "NULL" << endl;
return true; //这里写false还是true 无所谓!
// break; 不行 只能阻断循环!
}
while (p != NULL)
{
cout << p->data << " " ;
p = p->next;
if(p->next == NULL) //这里用指针来去掉结尾的多余空格!
{
cout << p->data;
//return true; //这个也行!
break; //这里可以用break!!!
}
// cout << endl;
}
return true; //循环结束后再return true!
}
int main()
{
LinkList L1,L2,L3; //可以三行变一行
L1 = CreateList();
L2 = CreateList();
/* CreateList(L1);
CreateList(L2);*/ //这样类似的代码不可以 有歧义!
L3 = Merge(L1, L2);
Print(L3);
return 0;
}
我的一些问题
1.如何创建多个链表
LinkList CreateList(),最后return L;
主函数中 L1 = CreateList(); L2 = CreateList();即可
2.如何顺次输入这些数直到-1停止
while(1) or while(cin >> e) 到-1之后使用break
3.如何比较两个单链表中data域的值并存放在链表L3中?
再设两个可以移动的指针来遍历
4.相等的数据怎么办?
直接放进来就可以!放一个就行!
5.其中一个遍历完了怎么办?
p1,p2本身即是降序排列,不用操心,直接把剩下的那个链表剩余的结点连到后面即可
6.怎么连?
用三目运算符!!或者循环
7.总结
(1)break的用法:终止当前循环。
(2)注意题目是否要求创建新的链表。
(3)使用指针p->next = NULL来去掉最后的空格。
(4)结合形成第三个链表之后让前两个链表指向空!
(5)创建一个指向链表的指针的思路很重要,遍历链表,删除结点,寻找某个节点都用得到!
完结撒花~!
2021.10.2
22:25