查看链表是否有环(数据结构C++表示)
2015-07-30 16:10
495 查看
查看链表是否有环有两种方法:
方法一:声明两个指针cur1和cur2,让cur1->next每次都指向下一个结点,cur2每一次都从第一个节点指到cur1当前的结点,然后判断两个指针指向同一个节点的步数,如果步数一样,则说明还没有找到环。如果步数不一样,则说明找到环了。
方法二:声明两个指针p和q,p每次走一步,q每次走两步,然后判断p和q是否相等,如果相等的话,说明有环,因为只有在有环的状况下,q走了一圈,然后追上p点。
方法一:声明两个指针cur1和cur2,让cur1->next每次都指向下一个结点,cur2每一次都从第一个节点指到cur1当前的结点,然后判断两个指针指向同一个节点的步数,如果步数一样,则说明还没有找到环。如果步数不一样,则说明找到环了。
方法二:声明两个指针p和q,p每次走一步,q每次走两步,然后判断p和q是否相等,如果相等的话,说明有环,因为只有在有环的状况下,q走了一圈,然后追上p点。
#include <stdio.h> #include <stdlib.h> #include <time.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Status; typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }Node,*LinkList; Status InitList(LinkList *L) { *L = (LinkList)malloc(sizeof(Node)); if(!(*L)) { return ERROR; } (*L)->next = NULL; return OK; } int ListLength(LinkList L) { int i=0; LinkList p = L->next; while(p) { i++; p = p->next; } return i; } void CreateListHead(LinkList *L, int n) { LinkList p; int i; srand(time(0)); *L = (LinkList)malloc(sizeof(Node)); (*L)->next = NULL; for(i=0; i<n; i++) { p = (LinkList)malloc(sizeof(Node)); p->data = rand()%100+1; p->next = (*L)->next; (*L)->next = p; } } void CreateListTail(LinkList *L, int n) { LinkList p,r; int i; srand(time(0)); *L = (LinkList)malloc(sizeof(Node)); if(!(*L)) { return; } r = *L; for(i=0; i<n; i++) { p = (Node*)malloc(sizeof(Node)); p->data = rand()%100+1; r->next = p; r = p; } r->next = (*L)->next->next; } //比较步数的方法 int HasLoop1(LinkList L) { LinkList cur1 = L; //定义结点cur1 int pos1 = 0; //cur1的步数 while(cur1) //cur1结点存在 { LinkList cur2 = L;//定义结点cur2 int pos2 = 0; //cur2的步数 while(cur2) //cur2结点存在 { if(cur2==cur1) { /*当cur1与cur2到达相同结点时 走过的步数一样,说明没有环*/ if(pos1==pos2) { break; } else { printf("环的位置在第%d个结点处。\n\n",pos2); return 1; //有环并返回1 } } cur2 = cur2->next; pos2++; } cur1 = cur1->next; pos1++; } return 0; } int HasLoop2(LinkList L) { LinkList p = L; LinkList q = L; while(p!=NULL && q!=NULL && q->next!=NULL) { p = p->next; if(q->next != NULL) { q = q->next->next; } printf("q:%d, q:%d\n",p->data, q->data); if(p==q) { return 1; } } return 0; } int main() { LinkList L; Status i; char opp; ElemType e; int find; int tmp; printf("\n1.创建有环链表(尾插法) \n2.创建无环链表(头插法) \n3.判断链表是否有环 0.退出\n\n"); while(opp != '0') { scanf("%c",&opp); switch(opp) { case '1': { CreateListTail(&L,10); printf("成功创建有环L(尾插法)\n"); break; } case '2': { CreateListHead(&L,10); printf("成功创建有环L(头插法)\n"); break; } case '3': { printf("方法一:\n\n"); if(HasLoop1(L)) { printf("结论:链表有环\n\n\n"); } else { printf("结论:链表无环\n\n\n"); } printf("方法二:\n\n"); if(HasLoop2(L)) { printf("结论:链表有环\n\n\n"); } else { printf("结论:链表无环\n\n\n"); } printf("\n"); break; } case '0': { exit(0); break; } } } return 0; }
相关文章推荐
- [C/C++]反转链表
- 关于指针的一些事情
- C#实现基于链表的内存记事本实例
- C# Pointer指针应用实例简述
- C++智能指针实例详解
- C++指向函数的指针实例解析
- 关于c语言指针的两处小tip分享
- 浅析iterator与指针的区别
- 探讨C++中数组名与指针的用法比较分析
- 详解C++中的指针、数组指针与函数指针
- C语言实现带头结点的链表的创建、查找、插入、删除操作
- C语言安全之数组长度与指针实例解析
- C++中指向对象的常指针与指向常对象的指针详解
- 指向变量的常指针与指向常变量的指针详细解析
- C#通过指针实现快速拷贝的方法
- C++实现简单的学生管理系统
- php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
- C#通过指针读取文件的方法
- C语言指针学习经验总结浅谈
- Linux内核链表实现过程