单链表环的问题
来源:互联网 发布:snmp代理软件 编辑:程序博客网 时间:2024/06/11 00:11
1.判断单链表是否有环
使用两个slow, fast指针从头开始扫描链表。指针slow 每次走1步,指针fast每次走2步。如果存在环,则指针slow、fast会相遇;如果不存在环,指针fast遇到NULL退出。
就是所谓的追击相遇问题:
代码示例如下:
//判断链表是否有环,如果无环返回NULLListNode* HasCircle(LinkList head){if(head==NULL)return NULL;ListNode *slow=head;ListNode *fast=head;while(fast!=NULL){slow=slow->next;//走一步fast=fast->next;if(fast!=NULL)fast=fast->next;elsereturn NULL;//如果slow==fast,则有环if(slow==fast)return slow;}//while条件为假,则退出循环return NULL;}
2.求有环单链表的环连接点位置
第一次碰撞点Pos到连接点Join的距离=头指针到连接点Join的距离,因此,分别从第一次碰撞点Pos、头指针head开始走,相遇的那个点就是连接点。
在环上相遇后,记录第一次相遇点为Pos,连接点为Join,假设头结点到连接点的长度为LenA,连接点到第一次相遇点的长度为x,环长为R。
第一次相遇时,slow走的长度 S = LenA + x;
第一次相遇时,fast走的长度 2S = LenA + n*R + x;
所以可以知道,LenA + x = n*R; LenA = n*R -x;
代码示例如下:
//判断一个链表是否有环,如果有,返回环的入口点;如果无环,则返回NULLListNode* CircleEntrance(LinkList head){if(head==NULL)return NULL;ListNode *slow=head;ListNode *fast=head;while(fast!=NULL){slow=slow->next;//走一步fast=fast->next;if(fast!=NULL)fast=fast->next;elsereturn NULL;//如果slow==fast,则有环if(slow==fast)break;}//while条件为假,则退出循环if(fast==NULL)//无环退出return NULL;else{//求入口点位置slow=head;while(slow!=fast){slow=slow->next;fast=fast->next;}return slow;}}
3.求有环单链表的环长
已知环的起点,很容易求环的长度。
示例代码如下:
//如果一个链表有环,返回环的长度;无环,则返回0int CircleLength(LinkList head){if(head==NULL)return 0;ListNode *slow=head;ListNode *fast=head;while(fast!=NULL){slow=slow->next;//走一步fast=fast->next;if(fast!=NULL)fast=fast->next;elsereturn 0;//如果slow==fast,则有环if(slow==fast)break;}//while条件为假,则退出循环if(fast==NULL)//无环退出return 0;else{slow=head;while(slow!=fast){slow=slow->next;fast=fast->next;}//while()slow指向int circlelen=1;ListNode *p=slow;//求环的长度while(p->next!=slow){++circlelen;p=p->next;}return circlelen;}}
4.求有环单链表的链表长
上述3中求出了环的长度;2中求出了连接点的位置,就可以求出头结点到连接点的长度。两者相加就是链表的长度。
5.尾插法建立链表
typedef struct ListNode{int data;struct ListNode* next;}ListNode,*LinkList;//尾插法创建带环的链表LinkList CreateLinkList(){LinkList head=NULL;ListNode *pre=NULL,*inter=NULL;//尾插法建立链表for(int i=1;i<=6;i++){//创建结点ListNode *temp=(ListNode*)malloc(sizeof(ListNode));temp->data=i;temp->next=NULL;if(head==NULL){head=temp;pre=head;}else{pre->next=temp;pre=temp;//尾插法}if(i==6)inter=temp;//i==3值处为交叉点}pre->next=inter;//建立链表的环return head;}
6.测试代码
int main(){LinkList head=CreateLinkList();int circlelen=CircleLength(head);if(!circlelen)cout<<"no circle"<<endl;else{cout<<"has circle"<<endl;cout<<"circle entrance is "<<circlelen<<endl;}return 0;}
0 0
- 判断单链表环的问题
- 判断单链表环的问题
- 单链表环的问题
- 关于单链表环的相关问题
- 问题背后的问题
- 关于问题的问题
- 问题背后的问题
- 有问题的问题?.?
- 的问题
- 面试题_单链表环的问题
- 单链表环存在问题的数学证明
- 单链表环的系列问题,及图解
- 问题++: firefox的关闭问题
- 问题:input类型的问题
- 百鸡问题的问题
- 5.4 关于问题的问题
- 优化问题的对偶问题
- [问题]AS的问题集锦
- 欢迎使用CSDN-markdown编辑器
- 算法路-HDU-ACM---1001
- 将字符串数字转换为数字
- Android基础-11
- 算法路-HDU-ACM---1002
- 单链表环的问题
- 关于tableview的 [self.tableView registerClass: forCellReuseIdentifier:使用方法
- 第20课时,自测
- 希尔排序算法
- Arcgis for js加载百度地图
- 第21课时,自测
- 更新开源项目cocopods spec版本
- 苹果App Store开发者帐户从申请,验证,到发布应用(3)
- 【Python笔记】如何源码编译依赖LAPACK和ATLAS库的NumPy包