在《剑指offer》里有一道笔试面试题:合并两个有序单链表,使得合并后的链表仍然有序。书中巧妙的利用了递归方法实现了该函数功能。
- 显然,利用递归算法能够让代码看起来非常简洁且容易看懂,但如果算法中涉及到多次参数调用和临时变量,会可饿能会导致函数深度递归,还有可能严重消耗系统堆栈的资源。
- 下面依次给出了基于递归法和基于循环法实现该函数功能,并通过测试通过。
基于循环法:
Node *Merge(Node *pH1,Node *pH2)
{// 合并两个有序链表
Node *pHead1=pH1;
Node *pHead2=pH2;
if(pHead2==NULL && pHead2==NULL)
return NULL;
if(pHead1!=NULL && pHead2==NULL)
return pHead1;
if(pHead1==NULL && pHead2!=NULL)
return pHead2;
Node *pMergedHead;
//判定两个链表第一个结点数的大小,指定较小者为合并链表的头结点
if(pHead1->m_nValue > pHead2->m_nValue) {
pMergedHead=pHead2;
pHead2=pHead2->m_pNext;}
else{
pMergedHead=pHead1;
pHead1=pHead1->m_pNext;}
Node *pFlag=pMergedHead;
while(pHead1!=NULL && pHead2!=NULL)
{
if(pHead1->m_nValue < pHead2->m_nValue){
pFlag->m_pNext=pHead1;
pFlag=pHead1;
pHead1=pHead1->m_pNext;
}//如果链表1中的结点值小于链表2中的结点值
else{
pFlag->m_pNext=pHead2;
pFlag=pHead2;
pHead2=pHead2->m_pNext;
}//如果链表2中的结点值小于链表1中的结点值
}
if(pHead1==NULL)//如果List1的长度小于List2的长度
pFlag->m_pNext=pHead2;
else //如果List2的长度小于List1的长度
pFlag->m_pNext=pHead1;
return pMergedHead;
}
基于递归法:
Node *MergeList(Node* List1,Node* List2)
{
if(List1==NULL && List2==NULL) return NULL;
if(List1==NULL && List2!=NULL) return List2;
if(List2==NULL && List1!=NULL) return List1;
Node *Merge=NULL;
if(List1->m_nValue<List2->m_nValue){
Merge=List1;
Merge->m_pNext=MergeList(List1->m_pNext ,List2);
}
else{
Merge=List2;
Merge->m_pNext=MergeList(List1,List2->m_pNext);
}
return Merge;
}
其他相关定义和函数:
#include <iostream>
#include <string>
using std::endl;
using std::cout;
using std::cin;
struct ListNode{
int m_nValue;
struct ListNode *m_pNext;
};
typedef struct ListNode Node;
Node *CreatList()
{//创建新链表
Node *List1,*Head,*temp;
Head=(Node *)malloc(sizeof(Node));
List1=Head;
List1->m_pNext=NULL;
int number;
int cnt=0;//计数器
int size;//链表长度size
cout<<"The size of the LinkList is: ";
cin>>size;
Head->m_nValue=size;
cout<<"Creat List Begine!"<<endl;
while(cnt<size){
temp=(Node *)malloc(sizeof(Node));
temp->m_pNext=NULL;
List1->m_pNext=temp;
List1=List1->m_pNext;
cout<<"Input a number:";
cin>>number;
List1->m_nValue=number;
cnt++;
}
return Head;
}
void PrintList(Node *PrList)
{//打印合并的链表
Node *temp=PrList;
cout<<"Print Begins!"<<endl;
while(temp){
cout<<temp->m_nValue<<" ";
temp=temp->m_pNext;
}
cout<<endl;
}
//主函数main
int main()
{
Node *La,*Lb,*Lc;
cout<<"Creat one LinkList."<<endl;
La=CreatList();
cout<<"successfully created!"<<endl;
cout<<endl<<"Creat another LinkList."<<endl;
Lb=CreatList();
cout<<"successfully created!"<<endl;
cout<<endl<<"Merge the Lists."<<endl;
cout<<"Merge Begins."<<endl;
Lc=MergeList(La->m_pNext,Lb->m_pNext);
cout<<endl<<"Print the MergeList."<<endl;
PrintList(Lc);
return 0;
}