链表动静构造法

对于链表的增删改查操作是数据结构的基础,但是当我们提交代码的时候经常会遇到头结点的判断出错问题,这里以leetcode的一道题为例重点记录下构建链表的动静态初始化方法,可以包含头结点的处理,不用对头结点做单独处理。

Merge Two Sorted Lists

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

示例:

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

这道题很简单,只要初始化定义两个指针p1和p2,分别指向两个链表,把小的那个节点构建到新的链表中即可。

这里给出模板:

//新定义的链表头指针的前一个指针
ListNode* pre_head = new ListNode(-1);
//用来指向尾节点
ListNode* tmp = head;
while(something){
    //把tmp指向下一个节点
    tmp->next = l1;
    //把tmp更新为尾节点
    tmp = tmp->next;
}
已这道题为例,代码如下:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
	if (!l1) {
		return l2;
	}
	if (!l2) {
		return l1;
	}
	ListNode* head = new ListNode(-1);
	ListNode* tmp = head;
	while (l1 && l2) {
		if (l1->val >= l2->val) {
			tmp->next = l2;
			tmp = tmp->next;
			l2 = l2->next;
		}
		else {
			tmp->next = l1;
			tmp = tmp->next;
			l1 = l1->next;
		}
	}
	if (!l1 && l2) {
		tmp->next = l2;
	}
	if (l1 && !l2) {
		tmp->next = l1;
	}
	return head->next;
    }

这种情况已经包含了头结点的情况,因为最后返回head->next,即使两个链表都为空,则head->next也为空,返回的依然为空指针。

如果是删除节点,a->b->c,我们要删除节点b,一般的做法是找到删除节点的前一个节点a,把a的下一个指针指向c,并删除b节点。但是如果是删除头结点a怎么办呢?a可是没有前驱节点的,所以如果不考虑这种情况就会报错。而用静态初始化链表法(静态声明pre_head节点),并把pre_head的下一个指针指向头结点(动态绑定旧链表),便可以解决删除头结点的问题:找到头结点head的前一个节点pre_head,把pre_head的next指向head的next,删除head,便完成了head头结点的删除,使代码具有统一性,健壮性更强。

ListNode* pre_head = new ListNode(-1);

pre_head->next=head

删除节点的代码如下(这里假设待删除节点):

void deleteNode(ListNode* head, ListNode* deleteNode) {
	ListNode* pre_head = new ListNode(-1);
	ListNode* tmp = pre_head;
	pre_head->next = head;

	ListNode* preDeleteNode = tmp;

	while (tmp != deleteNode) {
		preDeleteNode = tmp;
		tmp = tmp->next;
	}
	//preDeleteNode为待删除节点deleteNode的头一个节点
	preDeleteNode->next = tmp->next;
	delete tmp;
}
这种静动态构造链表的方法非常重要,以后测试用例如果未通过(特别是关于 头结点的特殊节点报错),请考虑这种方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值