题目描述:
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
输入:{1,3,5},{2,4,6}
输出:{1,2,3,4,5,6}
C++代码
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
//注意:不知道链表长度,要考虑两个链表的长度
#if 0
//不带头结点
//第一个结点就存放了数值
ListNode* head = NULL;//存放最终结果的链表:头指针,需要指向第一个结点
ListNode* work = NULL;//工作指针
/*解题思路:
最先比较链表1和链表2的第一个数值,保存小的数值;(假如链表1的第一个数值比链表2的第一个数值小)接下遍历链表1的第2个数值,
再和链表2的第一个数值进行比较,假如此时链表1中的值还是比链表2的第一个数值小,接着遍历数值较小的链表(即链表1),注意:链表2一直没动
假定遍历到链表1的倒数第2个数值,再把这个数值和链表2中的第一个数值进行比较发现,链表2的第一个数值终于比链表1中的值小了,则把链表2中第一个数值保存到结果中,
接下来就是遍历链表2的第二个数值和链表1的倒数第2个数值进行比较。。。。。。。比较到链表1或者链表2的链尾就不需要再比较
*/
//遍历pHead1的数值
while (1)
{
if (pHead1 == NULL)
{
if (head != NULL)
{
work->next = pHead2;
}
else
{
work = pHead2;
head = pHead2;
}
break;
}
if (pHead2 == NULL)
{
if (head != NULL)
work->next = pHead1;
else
{
work = pHead1;
head = pHead1;
}
break;
}
//一直遍历数值小的链表
if ((pHead1 != NULL && pHead2 != NULL) && pHead1->val <= pHead2->val)//链表1的数值小于链表2的当前值
{
//把链表1中的数值存入结果中
ListNode* s1 = (ListNode*)malloc(sizeof(ListNode));//申请结点
//ListNode * s1= new ListNode(5);//使用构造函数初始化
s1->val = pHead1->val;
s1->next = NULL;
if (head == NULL)//才开始初始化为了空指针
{
work = s1;
head = s1;
}
else
{
work->next = s1;//把工作指针指向s1
work = s1;//插入一点后,把工作指针移到新插入的结点
}
//接着遍历链表1中的值,链表2不动
pHead1 = pHead1->next;
}
//判断数值前要确认这个指针不是空指针
if ((pHead1 != NULL && pHead2 != NULL) && pHead1->val > pHead2->val)//链表1的数值大于链表2的当前值
{
//把链表2中的数值存入结果中
ListNode* s1 = (ListNode*)malloc(sizeof(ListNode));//申请结点
s1->val = pHead2->val;
s1->next = NULL;
if (head == NULL)//才开始初始化为了空指针
{
work = s1;
head = s1;
}
else
{
work->next = s1;//把工作指针指向s1
work = s1;//插入一点后,把工作指针移到新插入的结点
}
//接着遍历链表2中的值,链表1不动
pHead2 = pHead2->next;
}
}
return head;
#endif
#if 0//带头结点
/*解题思路和上面一样,但对链表中的值不需要新建结点
定义一个带头结点的空链表,p是工作指针,在p->next后面插入新的结点
比较两个链表的值,如果链表1的值比链表2要小,就这个值所在的结点链接到p;p再移到新链接的结点(p=p->next),进行下一次比较
*/
ListNode* head = new ListNode(-1);//定义头结点
ListNode* p;//工作指针
p = head;
p->next = NULL;//初始化一个空链表
while (pHead1 != NULL && pHead2 != NULL)
{
if (pHead1->val <= pHead2->val)
{
p->next = pHead1;
pHead1 = pHead1->next;//遍历链表1后面的值
}
else
{
p->next = pHead2;
pHead2 = pHead2->next;//遍历链表2后面的值
}
p = p->next;
}
//遍历完了链表1或者链表2,可能出现,两个链表的长度不一致,把较长的链表剩下的部分链接到p后面
if (pHead2 == NULL)
p->next = pHead1;
if (pHead1 == NULL)
p->next = pHead2;
return head->next;//由于带了无意义的头结点,需要返回不带头结点的链表,因此直接返回head->next
#endif
#if 1//递归
/*
递归的三要素
1、明确递归终止条件;
2、给出递归终止时的处理办法;
3、提取重复的逻辑,缩小问题规模。
*/
/*明白递归函数的功能:比较两个结点的值,返回较小值所在的结点
1、明确递归终止条件:链表为空
2、给出递归终止时的处理办法:返回剩下的链表(可能为空、可能不为空)
3、提取重复的逻辑,缩小问题规模:重复比较两个结点的值,返回较小值所在的结点
*/
ListNode* head = NULL;
if (pHead1 == NULL)
return pHead2;
if (pHead2 == NULL)
return pHead1;
if (pHead1->val <= pHead2->val)
{
head = pHead1;
head->next = Merge(pHead1->next, pHead2);
}
else
{
head = pHead2;
head->next = Merge(pHead1, pHead2->next);
}
return head;
#endif
}