C语言数据结构 链表的合并

有的时候课本上的伪代码真的很让人而无语

今天复习了一下数据结构

发现了一伪代码是这么写的

void reverse_merge(LinkList &A,LinkList &B,LinkList &C)//把元素
递增排列的链表A 和B 合并为C,且C 中元素递减排列,使用原空间
{
pa=A->next;pb=B->next;pre=NULL; //pa 和pb 分别指向A,B 的当前元素
while(pa||pb)
{
if(pa->data<pb->data||!pb)
{
pc=pa;q=pa->next;pa->next=pre;pa=q; //将A 的元素插入新表
}
else
{
pc=pb;q=pb->next;pb->next=pre;pb=q; //将B 的元素插入新表
}
pre=pc;
}
C=A;A->next=pc; //构造新表头
}//reverse_merge
分析:本算法的思想是,按从小到大的顺序依次把A 和B 的元素插入新表的
头部pc 处,最后处理A 或B 的剩余元素.

我建了个链表 升序排列以后 用这个代码改 程序老是死亡。。。

最后发现是if(pa->data<pb->data||!pb)出现了问题,怪谁呢?还是自己学的不好。。。

代码还算清晰 今天没白忙^!^

# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define SRAND 501  //产生SRAND以内的随机数
# define M 60  //产生M个随机数
typedef struct LB{    //链表Lian Biao
	int data;   //当前结点的值
	struct LB* Q; //指向下一节点的指针Q
}LB;
LB *Insert(LB *head,int DATA);  //在已经按照升序排列的链表中插入节点值DATA 返回插入新热点之后的头指针
LB *HB(LB *A,LB *B);//合并  把元素递增的链表A B 合并成递减排列 ,使用原来的空间 返回合并后的头结点
int main(){
    int i;
    LB *P=NULL,*S=NULL,*T=NULL,*X,*Y;
	srand(time(NULL));//产生随机种子
	for(i=0;i<M;i++)
	{
		P=Insert(P,rand()%SRAND);
		S=Insert(S,rand()%SRAND);
	}
    X=P;Y=S;
    printf("P链表<升序>:\n");
	for(i=0;i<M;i++)
	{
		printf("%03d%c",X->data,(i+1)%10?' ':'\n');
	   X=X->Q;
	}
	printf("S链表<升序>:\n");
	for(i=0;i<M;i++)
	{
		printf("%03d%c",Y->data,(i+1)%10?' ':'\n');
	   Y=Y->Q;
	}
	T=HB(P,S);
	printf("合并后的T链表<降序>:\n");
	for(i=0;i<2*M;i++)
	{
		printf("%03d%c",T->data,(i+1)%10?' ':'\n');
	   T=T->Q;
	}
	return 0;
}
LB *HB(LB *A,LB *B)
{
	LB *pa=A,*pb=B,*pre=NULL,*C,*q; //pa 和pb 分别指向A,B 的当前元素
	while(pb||pa)   //pa pb 不都到结尾时
	{
		if(pb&&pa&&pa->data<pb->data||!pb)//当pa  pb 都没到头且pa->data<pb->data  或者 pb到头时
		{               //将A 的元素插入新表
			C=pa;       //C指向当前节点
			q=pa->Q;    //q保存当前节点的下一节点
			pa->Q=pre;    //pa的下一个节点指向pre
			pa=q;          //pa更新到下一节点
		}
		else         //将B 的元素插入新表
		{
			C=pb;
			q=pb->Q;
			pb->Q=pre;
			pb=q;             
		}
	   pre=C;    //pre保存最新节点
	}
	return C; 
}
LB *Insert(LB *head,int DATA)  //在已经按照升序排列的链表中插入节点值DATA 返回插入及热点之后的头指针
{
	LB *R=head,*S=head,*temp=NULL;
	S=(LB *)malloc(sizeof(LB));
	if(!S)   //当新节点申请内存失败时
	{
		printf("申请内存失败,程序停止运行!\n");
		getchar();
		exit (0);
	}
	S->Q=NULL;  //若申请成功,则对新节点初始化 
	S->data=DATA;  
	if(!head)    //如果原链表为空,则蒋则将新节点置为头结点
		head=S;
	else        //否则 当原链表有节点时
	{
		while(R->data<DATA&&R->Q)  //当未找到合适的位置 且链表没有到末尾时
		{
			temp=R;           
			R=R->Q;    
		}
		if(R->data>=DATA)     //当找到合适的节点时
		{
			if(R==head)          //如果插入的节点在头结点head 之前时
			{
				S->Q=head;      //这个地方最好画一下图 如果不理解的话
				head=S;    
			}
			else
			{
				R=temp;     //否则 在中间的某个位置插入新节点 不懂就画图
				S->Q=R->Q;
				R->Q=S;
			}
		}
		else            //否则当链表直到末尾之前都没有找到合适的位置 则说明其应直接做尾节点
			R->Q=S;
	}
	return head;     //返回头结点
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值