将两个递增的链表合并成一个递减的链表(相同的元素只留下一个),并要求利用原表结点

原题:已知两个链表A和B,其元素值递增排序,编程将A和B合并成一个递减有序(相同元素只留下一个)的链表C,并要求利用原表节点。
分析:该程序是由LNode *MergeList()函数完成题设要求的,该函数的原理:采用插入在表头的方法实现先插入的值小的节点在表尾(相当于被后插入的结点推向表尾),而后插入的值大的结点在表头。此外,该程序的链表都是有头结点的。

#include		
#include		
#include      
#include
#include
struct LinkList	    //表结点定义
{
	int data;
	LinkList *next;
};
struct LNode	 //头结点定义
{
	LinkList *next;
};
LinkList *head;
LNode *hp=NULL;
int static flag=1;

int DisplayList(LNode *head)//输出链表中的数据域的值
{
	if(head->next==NULL)
	{
		printf("链表为空!\n");
		return 0;
	}
	LinkList *p;
	p=head->next;
	while(p->next!=NULL)
	{
		printf("%5d ->",p->data);
		p=p->next;
	}
	printf("%5d",p->data);	//输出最后一个数据
	printf("\n");
	return 0;
}
LNode *Create()//生成链表的函数
{
	int i=0;
	LinkList *p=NULL;
	LinkList *q=NULL;
	head=NULL;
	if(0 == flag)
	{
		srand( (unsigned)time( NULL ) );
		flag=1;
	}
	else
	{
		flag=0;
	}
	for(i=0;i<10;i++)
	{
		p=(LinkList *)malloc(sizeof(LinkList));
		p->data=rand()%100*7;
		if(head==NULL)
			head=p;
		else
			q->next=p;
		q=p;
	}

	if(head!=NULL)
	{
		q->next=NULL;
	}
	hp=(LNode *)malloc(sizeof(LNode));
	hp->next=head;
	return(hp);
}
LNode *ListSort(LNode *head)//对链表进行排序(按数据域值从小到大排序)
{
	if(head->next==NULL || head->next->next==NULL)//链表为空或只有一个非头结点时直接返回
		return head;
	else
	{
		LinkList *pre,*lp,*p,*q,*s;
		pre=head->next;q=p=pre->next;pre->next=NULL;
		while(p!=NULL)
		{
			s=(LinkList *)malloc(sizeof(LinkList));
			s->data=q->data;s->next=NULL;
			p=p->next;free(q);q=p;//记得释放原结点
			if(s->data < head->next->data)
			{
				s->next=head->next;
				head->next=s;
			}
			else
			{
				pre=head->next;lp=pre->next;
				while(lp!=NULL && s->data > lp->data)
					if(s->data > lp->data)
					{
						pre=lp;lp=lp->next;
					}
					s->next=lp;pre->next=s;
			}
		}
		return head;
	}
}
LNode *DelrepetElem(LNode *head)//删除链表中重复的结点
{
	if(head->next!=NULL)		   

        /*注意如果链表为空(即只有头结点而没有数据结点的情况下)不做些判断,就执行以下代码将出现非法访问内存的错误*/
	{					
		LinkList *pre=head->next,*lp;
		if(pre->next!=NULL)
		{
			while(pre->next!=NULL)
				if(pre->data != pre->next->data)
					pre=pre->next;
				else
				{
					lp=pre->next;
					pre->next=lp->next;
					free(lp);
				}
		}
	}
	return head;
}
LNode *MergeList(LNode *headla,LNode *headlb)//合并两个递增有序的链表
{
	LinkList *la,*lb,*pc;
	LNode *lc;
	la=headla->next;free(headla);//释放la的头结点
	lb=headlb->next;free(headlb);//释放lb的头结点
	lc=(LNode *)malloc(sizeof(LNode));lc->next=NULL;
	while(la!=NULL && lb!=NULL)
	{
		if(la->data < lb->data)
		{
			pc=la;la=la->next;
		}
		else if(la->data > lb->data)
		{
			pc=lb;lb=lb->next;
		}
		else
		{
			pc=la;la=la->next;
			free(pc);pc=lb;lb=lb->next;
		}
		pc->next=lc->next;lc->next=pc;
	}
	while(la!=NULL)
	{
		pc=la;la=la->next;
		pc->next=lc->next;lc->next=pc;
	}
	while(lb!=NULL)
	{
		pc=lb;lb=lb->next;
		pc->next=lc->next;lc->next=pc;
	}
	
	return lc;
}
void main()
{
	LNode *headla,*headlb,*headlc;
	headla=Create();	//生成链表la
	headla=ListSort(headla);
	headla=DelrepetElem(headla);
	printf("经排序且删除相同元素后的链表la的数据为:\n");
	DisplayList(headla);
	
	headlb=Create();	//生成链表lb
	headlb=ListSort(headlb);
	headlb=DelrepetElem(headlb);
	printf("经排序且删除相同元素后的链表lb的数据为:\n");
	DisplayList(headlb);

	headlc=MergeList(headla,headlb);
	printf("合并链表la与lb后得到的新链表lc的数据为:\n");
	DisplayList(headlc);
}

你可能感兴趣的:(算法实例)