链表面试题之合并有序的两个线性表-递归和非递归的方法
合并,链式表,面试题,递归2016-06-23
pLinkNode merge_list(pLinkNode plist1,pLinkNode plist2)
{
pLinkNode plist3=NULL;
pLinkNode cur=NULL;
assert(plist1);
assert(plist2);
if(NULL == plist1->next) //传进来的有一个是空链表
{
return plist2;
}
else if(NULL == plist2->next)
{
return plist1;
}
if(plist1->next->data <= plist2->next->data) //使得plist3和开始数据最小的链表公用同一个头指针
{
plist3=plist1;
}
else
{
plist3=plist2;
}
plist1=plist1->next;
plist2=plist2->next;
cur=plist3;
while(plist1 != NULL && plist2 != NULL) //plist3依然是按照递增的顺序排列
{
if(plist1->data <= plist2->data)
{
cur->next=plist1;
cur=plist1;
plist1=plist1->next;
}
else
{
cur->next=plist2;
cur=plist2;
plist2=plist2->next;
}
}
while(plist1 != NULL) //链表中比较完成后依然有未比较完的数据,只执行其中的一个while循环
{
cur->next=plist1;
plist1=plist1->next;
}
while(plist2 != NULL)
{
cur->next=plist2;
plist2=plist2->next;
}
return plist3;
}#include"mergelist.h"
void text1()
{
pLinkNode ret=NULL;
LinkNode plist1;
LinkNode plist2;
Init_list(&plist1);
Init_list(&plist2);
printf("链表1的元素为:");
Pust_list(&plist1,3);
Pust_list(&plist1,5);
Pust_list(&plist1,8);
Pust_list(&plist1,11);
Print_list(&plist1);
printf("链表2的元素为:");
Pust_list(&plist2,2);
Pust_list(&plist2,8);
Pust_list(&plist2,9);
Pust_list(&plist2,15);
Print_list(&plist2);
printf("合并之后链表的元素为:");
ret=merge_list(&plist1,&plist2);
Print_list(ret);
Free_list(ret);
}
int main()
{
text1();
system("pause");
return 0;
}#ifndef __MERGELIST_H__
#define __MERGELIST_H__
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DateType;
typedef struct LinkNode
{
DateType data;
struct LinkNode *next;
}LinkNode,*pLinkNode;
void Init_list(pLinkNode plist);
void Pust_list(pLinkNode plist,DateType x); //尾插
pLinkNode merge_list(pLinkNode plist1,pLinkNode plist2); //合并两个有序链表
void Print_list(pLinkNode plist);
void Free_list(pLinkNode plist);
#endif //__MERGELIST_H__#include"mergelist.h"
void Init_list(pLinkNode plist)
{
assert(plist);
plist->next=NULL;
}
pLinkNode Create_Node(DateType x)
{
pLinkNode newNode=(pLinkNode)malloc(sizeof(LinkNode));
if(NULL == newNode)
{
printf("out of memory\n");
exit(EXIT_FAILURE);
}
newNode->data=x;
newNode->next=NULL;
return newNode;
}
void Pust_list(pLinkNode plist,DateType x)
{
pLinkNode cur=plist->next;
pLinkNode newNode=NULL;
assert(plist);
newNode=Create_Node(x);
if(NULL == plist->next) //空链表时
{
plist->next=newNode;
}
else
{
while(cur->next != NULL)
{
cur=cur->next;
}
cur->next=newNode;
}
}
pLinkNode merge_list(pLinkNode plist1,pLinkNode plist2)
{
pLinkNode plist3=NULL;
pLinkNode cur=NULL;
assert(plist1);
assert(plist2);
if(NULL == plist1->next) //传进来的有一个是空链表
{
return plist2;
}
else if(NULL == plist2->next)
{
return plist1;
}
if(plist1->next->data <= plist2->next->data) //使得plist3和开始数据最小的链表公用同一个头指针
{
plist3=plist1;
}
else
{
plist3=plist2;
}
plist1=plist1->next;
plist2=plist2->next;
cur=plist3;
while(plist1 != NULL && plist2 != NULL) //plist3依然是按照递增的顺序排列
{
if(plist1->data <= plist2->data)
{
cur->next=plist1;
cur=plist1;
plist1=plist1->next;
}
else
{
cur->next=plist2;
cur=plist2;
plist2=plist2->next;
}
}
while(plist1 != NULL) //链表中比较完成后依然有未比较完的数据,只执行其中的一个while循环
{
cur->next=plist1;
plist1=plist1->next;
}
while(plist2 != NULL)
{
cur->next=plist2;
plist2=plist2->next;
}
return plist3;
}
void Print_list(pLinkNode plist)
{
pLinkNode cur=plist->next;
assert(plist);
while(cur != NULL)
{
printf("%d->",cur->data);
cur=cur->next;
}
printf("over\n");
}
void Free_list(pLinkNode plist)
{
pLinkNode cur=plist->next;
pLinkNode tmp=NULL;
if(NULL == plist->next) //空链表
{
return ;
}
else if(NULL == plist->next->next) //只有一个结点
{
free(plist->next);
plist->next=NULL;
}
else
{
while(cur != NULL)
{
tmp=cur;
cur=cur->next;
free(tmp);
tmp=NULL;
}
}
plist=NULL;
}typedef struct LinkNode
{
DataType data;
struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
LinkNode *phead;
}LinkList,*pLinkList;
pLinkNode Merge_LinkList(pLinkList plist1,pLinkList plist2) //合并两个有序链表(非递归)
{
//利用尾插法
pLinkNode plist3=NULL;
pLinkNode tail=NULL; //是每次合并后的最后一个结点
pLinkNode p1=plist1->phead;
pLinkNode p2=plist2->phead;
if(p1 == p2) //如果两个链表相同
{
return p1;
}
if(p1 == NULL) //两个链表中有一个为空
{
return p2;
}
if(p2 == NULL)
{
return p1;
}
if(p1->data <= p2->data) //为新的链表选取新的头指针
{
plist3=p1;
tail=p1;
p1=p1->next;
}
else
{
plist3=p2;
tail=p2;
p2=p2->next;
}
while(p1 && p2)
{
//合并的过程,每次寻找两个链表中较小的那个值
if(p1->data <= p2->data)
{
tail->next=p1;
p1=p1->next;
tail=tail->next;
}
else
{
tail->next=p2;
p2=p2->next;
tail=tail->next;
}
}
if(p1 != NULL) //合并完成后是否有链表没有合并完成
{
tail->next=p1;
}
if(p2 != NULL)
{
tail->next=p2;
}
return plist3;
}pLinkNode _Merge_LinkList(pLinkNode plist1,pLinkNode plist2) //合并两个有序链表(递归)
{
pLinkNode plist3=NULL;
pLinkNode p1=plist1;
pLinkNode p2=plist2;
if(p1 == p2) //如果两个链表相同
{
return p1;
}
if(p1 == NULL) //两个链表中有一个为空
{
return p2;
}
if(p2 == NULL)
{
return p1;
}
if(p1->data <= p2->data)
{
plist3=p1;
plist3->next=_Merge_LinkList(p1->next,p2);
}
else
{
plist3=p2;
plist3->next=_Merge_LinkList(p1,p2->next);
}
return plist3;
}
void text8()
{
LinkList plist1;
LinkList plist2;
LinkList ret={0};
//1
Init_LinkList(&plist1);
Push_back(&plist1,3);
Push_back(&plist1,5);
Push_back(&plist1,8);
Push_back(&plist1,11);
printf("链表1的元素为:");
Print_LinkList(&plist1);
//2
Init_LinkList(&plist2);
Push_back(&plist2,2);
Push_back(&plist2,8);
Push_back(&plist2,9);
Push_back(&plist2,11);
Push_back(&plist2,15);
printf("链表2的元素为:");
Print_LinkList(&plist2);
//合并
printf("合并后的链表为:");
//ret.phead=Merge_LinkList(&plist1,&plist2); //使用递归的方法
ret.phead=_Merge_LinkList(plist1.phead,plist2.phead); //使用非递归的方法
Print_LinkList(&ret);
Free_LinkList(&ret);
}