两个有序单链表的合并(二路归并)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42391248/article/details/86370703

 第一种算法:

用Lc指向合并后的新表。pa,pb,pc分别作为La,Lb,Lc的工作指针,pa,pb初始化分别指向两个有序链表的第一个元素,pc初始化指向La。从第一个指针开始比较,哪个元素小,就接在Lc后面,如果两个元素相当,就把一个链表接在后面,删除另一个链表的那个元素,这样确保合并后的表内无重复元素。当一个表到达表尾结点为空时,将非空的表接在Lc表后面。

#include"linklist.cpp"
void Print(LinkNode *L)
{
	LinkNode *p=L;
	while(p->next!=NULL)
	{
		p=p->next;
		printf("%d ",p->data);
	}
} 
void MergeList(LinkNode *La,LinkNode *Lb,LinkNode *&Lc)
{
	LinkNode *pa=La->next,*pb=Lb->next,*pc,*q;
	Lc=pc=La;
	while(pa&&pb)
	{
		if(pa->data<pb->data)
		{
			pc->next=pa;
			pc=pc->next;
			pa=pa->next;
		}
		else if(pa->data>pb->data)
		{
			pc->next=pb;
			pc=pc->next;
			pb=pb->next;
		}else
		{
			pc->next=pa;
			pc=pc->next;
			pa=pa->next;
			q=pb->next;
			delete pb;
			pb=q;
		}	
	}
	pc->next=pa?pa:pb;//如果pa非空,就将pa接在Lc后面
}

int main()
{
	int a[]={1,7,13};
	int b[]={2,4,6,8,10,11};
	LinkNode *La,*Lb,*Lc;
	int na=3,nb=6;
	CreateListR(La,a,na);
	CreateListR(Lb,b,nb);
	MergeList(La,Lb,Lc);
	Print(Lc);	
	return 0;		
}

 第二种算法:

合并后的序列存在Lb链表里面。pa,pb作为工作指针,初始化指向La,Lb的第一个元素。从第一个元素比较,如果pa小于pb,就将pa插在pb前面,直到有一个表到达表尾为空为止,最后判断La是否到达表尾,如果没有到达就将pa接在pb后面。

#include"linklist.cpp"
void Print(LinkNode *L)
{
	LinkNode *p=L;
	while(p->next!=NULL)
	{
		p=p->next;
		printf("%d ",p->data);
	}
} 
void MergeList(LinkNode *La,LinkNode *Lb)
{
	LinkNode *pa=La->next,*pb=Lb->next;
	int i=0,j=0;
	while(pa&&pb)
	{
		if(pa->data<pb->data)
		{
			i++;
			ListInsert(Lb,j+1,pa->data);
			pa=pa->next;
			j++;
		}
		else if(pa->data==pb->data)
		{
			i++;
			j++;
			pa=pa->next;
			pb=pb->next;
		}
		else
		{
			j++;
			pb=pb->next;
		}		
	}
	while(pa)
	{
		ListInsert(Lb,j+1,pa->data);
		pa=pa->next;
		j++;
	}
}

int main()
{
	int a[]={1,4,12};
	int b[]={2,4,6,8,10,11};
	LinkNode *La,*Lb;
	CreateListR(La,a,3);
	CreateListR(Lb,b,6);
	MergeList(La,Lb);
	Print(Lb);		
	return 0;		
}

 linklist.cpp头文件:

//单链表基本运算算法
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode  
{
	ElemType data;
	struct LNode *next;		//指向后继结点
} LinkNode;					//声明单链表结点类型
void CreateListF(LinkNode *&L,ElemType a[],int n)
//头插法建立单链表
{
	LinkNode *s;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data=a[i];
		s->next=L->next;			//将结点s插在原开始结点之前,头结点之后
		L->next=s;
	}
}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立单链表
{
	LinkNode *s,*r;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	r=L;					//r始终指向终端结点,开始时指向头结点
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data=a[i];
		r->next=s;			//将结点s插入结点r之后
		r=s;
	}
	r->next=NULL;			//终端结点next域置为NULL
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
}
void DestroyList(LinkNode *&L)
{
	LinkNode *pre=L,*p=pre->next;
	while (p!=NULL)
	{	free(pre);
		pre=p;
		p=pre->next;
	}
	free(pre);	//此时p为NULL,pre指向尾结点,释放它
}
bool ListEmpty(LinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;int i=0;
	while (p->next!=NULL)
	{	i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=NULL)
	{	printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L;
	if (i<=0) return false;		//i错误返回假
	while (j<i && p!=NULL)
	{	j++;
		p=p->next;
	}
	if (p==NULL)				//不存在第i个数据结点
		return false;
	else						//存在第i个数据结点
	{	e=p->data;
		return true;
	}
}
int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n=1;
	while (p!=NULL && p->data!=e)
	{	p=p->next;
		n++;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j=0;
	LinkNode *p=L,*s;
	if (i<=0) return false;			//i错误返回假
	while (j<i-1 && p!=NULL)		//查找第i-1个结点p
	{	j++;
		p=p->next;
	}
	if (p==NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点*p
	{	s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
		s->data=e;
		s->next=p->next;			//将s结点插入到结点p之后
		p->next=s;
		return true;
	}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L,*q;
	if (i<=0) return false;		//i错误返回假
	while (j<i-1 && p!=NULL)	//查找第i-1个结点
	{	j++;
		p=p->next;
	}
	if (p==NULL)				//未找到位序为i-1的结点
		return false;
	else						//找到位序为i-1的结点p
	{	q=p->next;				//q指向要删除的结点
		if (q==NULL) 
			return false;		//若不存在第i个结点,返回false
		e=q->data;
		p->next=q->next;		//从单链表中删除q结点
		free(q);				//释放q结点
		return true;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42391248/article/details/86370703