快慢指针的常见应用

快慢指针:快慢指针是解决数组和链表问题的常用方法,该方法也被称为“龟兔算法”。从名称就可以看出气基本思想是使用两个指针以不同的速度在数组或链表中移动。在处理循环链表或数组时,此方法非常有用。

快慢指针的应用

(1)判断单链表是否存在环

如果链表存在环,就好像操场的跑道是一个环形一样,此时让快慢指针都从链表头开始遍历,快指针每次向前移动两个位置,慢指针每次向前移动一个位置;如果快指针到达NULL,说明链表以NULL为结尾,没有环。如果快指针追上慢指针,则表示有环。代码如下:

bool HasCircle(Node *head)
{
	if(head == NULL)
	  return false;
	Node *slow = head;//从链头开始遍历
	Node *fast = head;//从链头开始遍历
    while(fast != NULL && fast->next != NULL)
    {
    	slow = slow->next;//慢指针每次前进一步
    	fast = fast->next->next;//快指针每次前进两步
    	if(slow == fast)//相遇则存在环 
    		return true;
    }
    return false;
 }
    		

(2)在有序链表中寻找中位数

快指针的移动速度是慢指针移动速度的2倍,因为当快指针到达链表尾时,慢指针到达中点。

程序还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。

如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时可以根据”规则“返回上中位数或下中位数或(上中位数+下中位数)的一半。

while (fast && slow)
{
	if(fast->next == NULL)
	  return slow->data;
	else if (fast->next != NULL && fast->next->next == NULL)
	   return (slow->data + slow->next->data)/2;
	else
	{
		fast = fast->next;
		fast = fast->next;
		slow = slow->next;
	}
}

(3)输出链表中的倒数第K个结点(即正数第k-1个节点)

可以定义两个指针,第一个指针从链表的头指针开始遍历向前走K-1步,第二个指针保持不动;从第K步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在K-1,当第一个指针到达链表的尾节点时候,第二个指针正好是倒数第K个节点,代码如下:

//查找单链表中倒数第K个结点
ListNode * RGetKthNode(ListNode * pHead, unsingnes int k)//函数前面的R代表反向
{
	if(k == 0 || pHead == NULL)//这里k的计数是从1开始的,若k为0或链表为空返回NULL
	   return NULL;
	ListNode * pAhead = pHead;
	ListNode * pBehind = pHead;
	 
	 for(int i=0; i<k-1;i++)
	 {
	 	pAhead=pAhead->next;
	 	if(pAhead==NULL)
	 	return NULL;//当链表长度小于k时候,返回NULL
	 }
      while(pAhead->next !=NULL )//前后两个指针一起向前走,知道前面的指针指向最后一个结点
      {
      	PBehind = pBehind->next;
      	pAhead = pAhead->next;
      }
      return pBehind;//后面的指针所指结点就是倒数第K个结点
      	

参考链接:
https://blog.csdn.net/qq_21815981/article/details/79833976

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值