LeetCode ---- 合并两个有序链表

博主在LeetCode上做合并两个有序链表的题时,代码编译不过,合并结果少一个数。在VS下运行相同代码却正常。分析认为可能是编译器或链表初始化方式不同导致。同时给出了合并有序链表的思路。

 这是我刷了这么久LeetCode以来,最让我无语的一道题。合并两个有序链表,题确实不难。写完之后,一直编译不过,出现下面的傻逼问题,合并完之后就是少一个数。分析了两遍,甚至画了整个代码合并过程的图,觉得代码没有什么问题。但还是运行不过,让我真的很难受。实在没办法,就去VS下写了完整的单链表合并,一模一样的代码,VS下面运行出来的结果一点毛病都没有。 让我真的有一点怀疑,LeetCode里面的编译器真的是个傻逼。

 不管怎么样,目的还是学习。所以还是先看一下题目吧!

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:输入:1->2->4, 1->3->4

          输出:1->1->2->3->4->4

 

 合并的过程很好想,因为两个链表本身有序,所以不用考虑万一链表后面出现更大的数。这个过程简单来说就是先将新链表指向两个链表第一个节点值小的那个链表。然后依次遍历两个链表,将较小值的节点链到新链表后就行。思路就是这个思路,具体实现还是看这个非递归的代码比较合适。

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
struct ListNode
{
	int val;
	struct ListNode* next;
};

//初始化
void InitList(struct ListNode* l1)
{
	assert(l1 != NULL);
	l1->next = NULL;
}

//申请节点
static struct ListNode *GetNode(int val)
{
	struct ListNode*pGet = (struct ListNode*)malloc(sizeof(struct ListNode*));
	assert(pGet != NULL);
	pGet->val = val;
	pGet->next = NULL;
	return pGet;
}

//尾插
int Insert_tail(struct ListNode* l1, int val)
{
	assert(l1 != NULL);
	struct ListNode *p = l1;
	while (p->next != NULL)
	{
		p = p->next;
	}
	struct ListNode *pGet = GetNode(val);
	p->next = pGet;
	return 1;
}

//合并
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
	assert(l1 != NULL && l2 != NULL);
    assert((l1->next != NULL) && (l2->next != NULL));
	struct ListNode *p1 = l1->next;
	struct ListNode *p2 = l2->next;
	struct ListNode *new_List = (p1->val <= p2->val) ? l1 : l2;//比较两个有序链表哪个的第一个值小,小的链表将链表地址赋给新链表
	struct ListNode *tmp = new_List;

	while ((p1 != NULL) && (p2 != NULL))
	{
        //哪个的值小,就连接到新链表后
		if (p1->val <= p2->val)
		{
			tmp->next = p1;
			p1 = p1->next;
		}
		else
		{
			tmp->next = p2;
			p2 = p2->next;
		}
		tmp = tmp->next;
	}
    //出循环有可能其中一个链表的值还没有判断完,那么执行如下操作,将其直接链到新链表就OK
	if (p1 != NULL)
	{
		tmp->next = p1;
	}
	if (p2 != NULL)
	{
		tmp->next = p2;
	}
	return new_List;
}

//打印
void Show(struct ListNode* plist)
{
	assert(plist != NULL);
	struct ListNode *p = plist;
	while (p->next != NULL)
	{
		printf("%d ", p->next->val);
		p = p->next;
	}
	printf("\n");
}

int main()
{
	struct ListNode l1;
	struct ListNode l2;
	InitList(&l1);
	InitList(&l2);

	Insert_tail(&l1, 1);
	Insert_tail(&l1, 2);
	Insert_tail(&l1, 4);

	Insert_tail(&l2, 1);
	Insert_tail(&l2, 3);
	Insert_tail(&l2, 4);

	Show(&l1);
	Show(&l2);
	struct ListNode* new_list = mergeTwoLists(&l1,&l2);
	Show(new_list);

	return 0;
}

 

代码运行结果如上,至于为什么和LeetCode上运行结果不一样。我猜想可能是因为编译器,或者链表初始化的方式有所不同,导致运行结果又那么一丢丢小问题!但是没关系,问题不大,有一个正确的思路就OK。

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值