单链表的分隔

本文介绍两种将单链表拆分成两个子链表的方法,确保每个子链表的元素数量尽可能相等,且保持原有顺序。一种是通过遍历统计节点总数后划分,另一种使用快慢指针技巧实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

拆分单链表产生两个元素数目相等的子链表,维持原链表顺序,奇数个元素时第一个子链表多一个元素。当只有一个元素的时候 back == NULL。

第一种方案:先整个遍历链表统计链表节点总数目,按照节点的数目进行划分

        /* 
	 * 将单链表进行拆分,分为两部分,两部分元素数目相等, 总数是奇数时,前部分多一个 
         * 思路: 1. 先统计总数目。 2. 在进行划分
	 * 思路非常直观,代码易于书写。当n很大时效率不高。
	 */
	void partition_bruteforce(node *head, node * &front, node * &back)
	{
		if (!head)
		{
		 front = NULL;
		 back = NULL;
		 return;
		}
		int n = 0;
		node *p = NULL;
		for (p = head; p; n++,p = p->next); /* 统计链表中节点的个数 */
		int c = n / 2 + n % 2; /* 前半段中的元素数目,据此进行划分*/
		int i;
		node *tail = NULL;
		for (i = 0, p = head; i != c; i++, tail = p, p = p->next); /* 进行计数切分 */
		if (tail) tail->next = NULL;		
		front = head;
		back = p;
	}

	

第二种方案:采用slow pointer, fast pointer 的方式进行遍历

/*
	* 将单链表进行拆分,分为两部分,两部分元素数目相等, 总数是奇数时,前部分多一个。
	* 思路: 
	*      1. 设置快慢指针,快指针的速度是慢指针的2倍。 
	*      2. 快指针访问结束的时候,慢指针恰好在后半段的开头。
	*
	* 思路非常直观,代码易于书写,更有效率。 但是观察到这一现象并不容易。
	* 要注意多多思考,不要只拘泥于已经有的方案。
	****/
	void partition_smart(node *head, node * &front, node * &back)
	{
		if (!head) /* 特殊情况要加以考虑 */
		{
			front = NULL;
			back = NULL;
			return;
		}
		node *slow, *fast;
		slow = fast = head;
		node *tail = NULL;
		while (fast)
		{
			tail = slow;
			slow = slow->next;
			fast = fast->next ? fast->next->next : NULL; /* 很重要,一次访问2个不能保证前一个不空 */
		}
		
		tail->next = NULL;
		front = head;
		back = slow;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值