有序链表的合并
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
链表没有头结点。
有序合并的思想类似归并排序。
非递归的解决方式就是设置一个指针p一直标记着上一个合并完毕的结点的下一个结点,p在 l1 和 l2 之间来回移动,直到完成匹配。
递归的解决方式就是不停的把确定新的有序链表下一个结点的任务交给下一层递归来完成,当两条链表都检索完毕后,一个一个的返回之前上一层交给我下一层的任务,最后从后往前完成了有序链表的合并。
#include<iostream>
using namespace std;
//结点定义
typedef struct Node{
int data;
struct Node* next;
}ListNode,*LinkList;
//原地操作(非递归)
LinkList& mergeTwoLists1(LinkList& l1, LinkList& l2){
ListNode* p = NULL;
ListNode* head = NULL;
if(l1 && l2){
if(l1->data < l2->data){
head = l1;
p=l1;
l1=l1->next;
}else{
head = l2;
p=l2;
l2=l2->next;
}
while (l1 != NULL && l2 != NULL){
if (l1->data < l2->data){
p->next = l1;
l1 = l1->next;
} else{
p->next = l2;
l2 = l2->next;
}
p = p->next;
}
p->next = l1 == NULL ? l2 : l1;
return head;
}else if(l1 == NULL){
return l2;
}else if(l2 == NULL){
return l1;
}else return head;
}
//非原地操作(递归)
LinkList& mergeTwoLists2(LinkList& l1, LinkList& l2){
if (l1 == NULL){
return l2;
}else if (l2 == NULL){
return l1;
}else if (l1->data < l2->data){
l1->next = mergeTwoLists2(l1->next,l2);
return l1;
}else{
l2->next = mergeTwoLists2(l1,l2->next);
return l2;
}
}
//打印
void printValue(LinkList& head){
ListNode* p=head;
while(p != NULL){
cout<<p->data<<" ";
p=p->next;
}
}
int main(){
ListNode* head = new ListNode;
head->data = 1;
ListNode* l1 = new ListNode;
l1->data = 2;
head->next = l1;
ListNode* l2 = new ListNode;
l2->data = 5;
l1->next = l2;
ListNode* l3 = new ListNode;
l3->data = 6;
l2->next = NULL;
ListNode* l4 = new ListNode;
l4->data = 3;
l3->next = l4;
ListNode* l5 = new ListNode;
l5->data = 4;
l4->next = l5;
l5->next = NULL;
cout<<"合并前:"<<endl;
printValue(head);
cout<<endl;
printValue(l4);
cout<<endl;
cout<<"合并后:"<<endl;
ListNode* p=mergeTwoLists1(head,l4);
printValue(p);
}
运行结果: