热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

快慢指针和其简单应用

什么是快慢指针?快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2次,慢指针每次向前移动1

什么是快慢指针?

快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2次,慢指针每次向前移动1次。


快慢指针的常见应用

1.判断单链表是否为循环链表

       对于初学循环链表者,可能开始想到的方法就是使用双重循环。当外层循环步进一个节点时,内层循环就遍历外层循环那节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表是有循环的,反之则不存在循环。这种方法无疑效率比较低。

       而快慢指针应用于这个场景效率会明显提高。就像生活中的一个场景:一些人绕着环形跑道跑步,有的人快点,有的人慢点,过了一段时间会发现快的人又经过慢的人身旁,这就是循环跑。那么如果是理想直线跑道的话,两个人便不会相遇了,就没有绕圈即循环的性质。

       快慢指针的思想就是这样。快指针每次步进多个结点(视情况而定),慢指针每次只步进一个节点。那么如果该链表存在循环的话,快指针一定会再次碰到慢指针,反之则不存在循环。

代码示例:

bool isLoop(LinkList L) {LinkList fast, slow;fast = slow = L;while (fast && fast->next){slow = slow->next;fast = fast->next->next;if (slow == fast){return true; }}return false;
}


例如长度为8,从1开始:

123456781
135713571

注:还有可能不直接是一个环,而是部分有环。下面会说到如何找环的入口点。


2.在有序链表中寻找中位数

       该方法在不借助计数器变量的情况下,实现寻找中位数的功能。原理是:快指针的移动速度若是慢指针的2倍,当快指针到达链表尾部时,慢指针到达中点。可以想到尾部和中点的情况和节点数的奇偶有关。例如移动次数若为x,若1+2x到达了表尾,链表就有奇数个节点,此时慢指针为1+x,直接返回慢指针指向的数据即可。如果快指针指向倒数第二个节点,说明链表节点数为偶数,这时可以根据“规则”返回上中位数(1+x内容),下中位数(1+x+1内容),或者上下的平均数。

代码示例:

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


3.如果链表存在环,怎么找到环的入口点呢?

       有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成环。
       那么问题来了,如何判断一个链表是这类链表呢?即如果链表存在环,怎么找到入口点呢?
      ① 如果循环方式为上图所示,即尾部有循环,当fast(两倍速)与slow相遇时,slow一定没有走完链表。
      ②如果循环入口点为头结点,如上面表格情况,那么slow恰好遍历一圈。
       对于第一种情况(如上图),我们从链表头A点与相遇点P点分别设置一个指针,每次各走一步,两个指针必定相遇(一定存在循环啦),且第一次相遇点就是环的入口了。
       解释:A点为出发点,fast和slow在p点相遇,所以A->B->P 步数等于P->B->P  所以A->B等于P->B 那么如果在A点和p点分别设置一个指针,每次各走一步,两个指针就会在B点相遇,即相遇在环的入口处。
        对于第二种情况,相遇点即链表头,也就是环的入口了。

代码示例:      

node* findLoopPort(node *head){node *fast,*slow;fast=slow=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){break;}}if((fast==NULL)||(fast->next==NULL)){return NULL;// 没环 }//没有return ,相遇了... slow=head;//此时fast指在相遇点,slow回头,期待再次相遇... while(slow!=fast){slow=slow->next;fast=fast->next;}return slow;//又相遇了,相遇在了环的入口,return slow
}


4.扩展问题
       判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)。
比较好的两个方法:
       ①将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的第一个入口即为相交的第一个点。
       ②如果两个链表相交,两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表吗,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。
         这时我们记下两个链表length,再遍历一次,长链表节点先出发前进lengthMax-lengthMin
步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。


参考文章:http://www.cnblogs.com/hxsyl/p/4395794.html#top
                  百度百科




   



推荐阅读
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 探讨如何高效使用FastJSON进行JSON数据解析,特别是从复杂嵌套结构中提取特定字段值的方法。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 尽管某些细分市场如WAN优化表现不佳,但全球运营商路由器和交换机市场持续增长。根据最新研究,该市场预计在2023年达到202亿美元的规模。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 几何画板展示电场线与等势面的交互关系
    几何画板是一款功能强大的物理教学软件,具备丰富的绘图和度量工具。它不仅能够模拟物理实验过程,还能通过定量分析揭示物理现象背后的规律,尤其适用于难以在实际实验中展示的内容。本文将介绍如何使用几何画板演示电场线与等势面之间的关系。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
author-avatar
才客caike
才客,优质人才的私人职业顾问。一人一岗,专业专注!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有