两个有序单链表的合并

错误演示:

输入数据: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始终为空

分析:
在第一趟判断中按照本代码画示意图:
两个有序单链表的合并_第1张图片

第二趟:
两个有序单链表的合并_第2张图片
只需要两趟就可以发现问题
第一趟的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);
}

你可能感兴趣的:(数据结构)