两个有序单链表的合并

  • Post author:
  • Post category:其他




错误演示:

输入数据:La:3 1 Lb:6 4 2

La展示数据:1 3

Lb展示数据:2 4 6

void MergeSLinklist(LinkList &La, LinkList &Lb, LinkList &Lc)
{
	LinkList pa = La->next;
	LinkList pb = Lb->next;
	LinkList pc = Lc->next = NULL;
	while (pa&&pb)
	{
		if (pa->data <= pb->data)
		{
			printf("if\n");
			pc = pa;
			printf("PC->DATA:%d\n", pc->data);
			pa = pa->next;
			//printf("PA->DATA:%d\n", pa->data);//nullptr
			pc = pc->next;
			//printf("PC->DATA:%d\n", pc->data);
		}
		else {
			printf("else\n");
			pc = pb;
			//printf("PC->DATA:%d\n", pc->data);
			pc = pc->next;
			//printf("PC->DATA:%d\n", pc->data);
			pb = pb->next;
			printf("PB->DATA:%d\n", pb->data);
		}
	}
	pc->next = pa ? pb : pa;
	ShowSLinklist(Lc);
	free(Lb);
}


问题:pc始终为空

分析:

在第一趟判断中按照本代码画示意图:

在这里插入图片描述

第二趟:

在这里插入图片描述

只需要两趟就可以发现问题

第一趟的

pc=pc->next

,PC最后指向数据域为3的结点

第二趟的

pc=pc->next

,PC最后指向了数据域为4的结点

理应把数据域为3的结点放在pb数据域为2的结点后面

但是直接跳过了



错误思路

我之所以代码会这么写,是因为:

我以为

pc=pa

,就只是把pa当前的那个结点给了pc

然后

pc->next

应该为空

但其实pa后面的一起都跟过来了 。

所以会出现指向错误



至于为什么最后pc是空的是因为我,没看清三目运算符

pc->next = pa ? pb : pa;

这一句的意思:

如果pa为真,即pa非空。让

pc->next

的值为pb。

如果pa为假,即pa为空。让

pc->next

的值为pa。

由于循环结束的条件就是某一方为空

理应是:诺pa为空,放pb。pb为空放pa

所以正确的应该如下:

pc->next=pa?pa:pb;



正确逻辑代码

void MergeSLinklist(LinkList &La, LinkList &Lb, LinkList &Lc)
{
	LinkList pa = La->next;
	LinkList pb = Lb->next;
	LinkList pc;
	Lc = pc = La;
	while (pa&&pb) {
		if (pa->data <= pb->data)
		{
			pc->next = pa;
			pc = pa;
			pa = pa->next;
		}
		else {
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}	
	如果pa为空。即假命题,取pb
	不为空就取pa
	pc->next = pa ? pa : pb;
	free(Lb);
}



版权声明:本文为yliyp原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。