题目:
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。例如,输入下图中的链表1和链表2,则合并之后的升序链表如链表3所示,链表节点定义如下所示:
typedef struct Node
{
int mdata;
struct Node* pnext;
}Node,*PNode;
合并的递归思路:
链表1的头结点的值(注意:此处的头结点是指链表中的第一个数据节点,并不是指带头结点的链表)小于链表2的头结点的值,因此链表1 的头结点是合并后链表的头节点,再剩余的节点中链表2 的头节点的值小于链表1 得头节点的值,因此连链表2的头结点是剩余节点的头节点,把这个节点和之前已经合并好的链表的尾节点链接起来。
合并过程:
上述过程是一个典型的递归过程。
当两个链表中其中一个为空链表时,合并结果就是另一个不为空的链表,当都为空链表时合并后的链表就是一个空链表。
代码如下:(注意:下述递归代码仅限于不带头结点的单链表的合并,非递归代码仅限于带头结点的单链表的合并)
/*不带头结点的单链表的合并递归实现*/
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int mdata;
struct Node* pnext;
}Node,*PNode;
void Init(PNode* phead)
{
if (phead == NULL)
{
return;
}
*phead = NULL;
}
PNode BuyNode(ELEM_TYPE val)
{
PNode pnewnode = (PNode)malloc(sizeof(Node));
if (pnewnode == NULL)exit(0);
pnewnode->mdata = val;
pnewnode->pnext = NULL;
return pnewnode;
}
bool InsertTail(Node** phead, ELEM_TYPE val)
{
if (phead == NULL)
{
return false;
}
if (*phead == NULL)
{
PNode pnewnode = BuyNode(val);
*phead = pnewnode;
return true;
}
PNode pCur = *phead;
while (pCur->pnext != NULL)
{
pCur = pCur->pnext;
}
PNode pnewnode = BuyNode(val);
pCur->pnext = pnewnode;
return true;
}
//递归:合并两个有序单链表
PNode Merge(PNode pHead1,PNode pHead2)//pHead1和pHead2为两个链表的 第一个数据节点
{
if(pHead1==nullptr) return pHead2;
else if(pHead2==nullptr) return pHead1;
PNode pMergedHead=nullptr;
if(pHead1->mdata<pHead2->mdata)
{
pMergedHead=pHead1;
pMergedHead->pnext=Merge(pHead1->pnext,pHead2);
}
else
{
pMergedHead=pHead2;
pMergedHead->pnext=Merge(pHead1,pHead2->pnext);
}
return pMergedHead;
}
void Show(PNode phead)
{
PNode pCur = phead;
while (pCur != NULL)
{
printf("%d ", pCur->mdata);
pCur = pCur->pnext;
}
printf("\n");
}
int main()
{
PNode phead1,phead2;
Init(&phead1);
Init(&phead2);
int val=-1;
for(int i=0;i<4;i++)
{
val=val+2;
InsertTail(&phead1, val);
}
val=0;
for(int i=0;i<4;i++)
{
val=val+2;
InsertTail(&phead2, val);
}
Show(phead1);
Show(phead2);
PNode mer=Merge(phead1,phead2);
Show(mer);
return 0;
}
另外还有一种非递归的实现方法,思路不难,这里不再赘述,仅附上实现代码:
/*带头结点的单链表的合并非递归实现*/
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int mdata;
struct Node* pnext;
}Node, *Link;
void Init(Link phead)
{
assert(phead != NULL);
if (phead == NULL)
{
return;
}
phead->pnext = NULL;
}
Link BuyNode()
{
Node* pnewnode = (struct Node*)malloc(sizeof(struct Node));
assert(pnewnode != NULL);
pnewnode->pnext = NULL;
return pnewnode;
}
bool InsertTail(Link phead, ELEM_TYPE val)
{
if (phead == NULL)
{
return false;
}
Node* pCur = phead;
while (pCur->pnext != NULL)
{
pCur = pCur->pnext;
}
Node* pnewnode = BuyNode();
pnewnode->mdata = val;
pCur->pnext = pnewnode;
return true;
}
void Print(Link phead)
{
if (phead == NULL)
{
return;
}
struct Node* pCur = phead->pnext;
while (pCur != NULL)
{
printf("%d ", pCur->mdata);
pCur = pCur->pnext;
}
printf("\n");
}
Link NiceMerge(Link pHead1,Link pHead2)
{
if(pHead1==nullptr) return pHead2;
if(pHead2==nullptr) return pHead1;
pHead1=pHead1->pnext;
pHead2=pHead2->pnext;
Link pMergedHead=new Node();//合并后的链表的头结点
Link p=pMergedHead;//节点指针p用来遍历
while(pHead1!=nullptr && pHead2!=nullptr)
{
if(pHead1->mdata<=pHead2->mdata)
{
p->pnext=pHead1;
pHead1=pHead1->pnext;
}
else
{
p->pnext=pHead2;
pHead2=pHead2->pnext;
}
p=p->pnext;
}
if(pHead1!=nullptr)
{
p->pnext=pHead1;
}
else
{
p->pnext=pHead2;
}
return pMergedHead;
}
int main()
{
Node head1,head2;
Init(&head1);
Init(&head2);
int val=-1;
for(int i=0;i<4;i++)
{
val=val+2;
InsertTail(&head1, val);
}
val=0;
for(int i=0;i<4;i++)
{
val=val+2;
InsertTail(&head2, val);
}
Print(&head1);
Print(&head2);
Link mer=NiceMerge(&head1,&head2);
Print(mer);
return 0;
}