单链表是最常见的数据结构,带环的单链表不是很常见,但是在许多面试中出现的概率较高,其中不乏一些经典的问题,怎样判断单链表中是否有环。
单链表带环指的是如下这张图所示情况:
其实思想还是挺简单的:
我们需要两个指针,初始时都指向链表的头,之后指针同时移动,其中一个指针一次移动一步,另一个指针一步移动两步,如果两个指针有相等的可能,则链表就是有环的,否则,出现一个指针指向了 NULL ,那么这个链表就是肯定不带环的。
下面给出具体的实现:
#include <stdio.h> #include <malloc.h> typedef int DataType; typedef struct node { DataType data; struct node *next; }LinkedNode, *LinkList; LinkList create_list(int *a, int pos, int len); int is_exist_loop(LinkList list); int main(int argc, char **argv) { int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; LinkList list_head = NULL; int result = -1; list_head = create_list(array, 10, sizeof(array) / sizeof(int)); result = is_exist_loop(list_head); if(result == 0) { printf("This list has loop "); } else if(result == -1) { printf("This list don't has loop "); } else { printf("error "); } } /*根据条件建立单链表*/ /* * a 链表初始化数组 * pos 环的位置,若为 0 或者大于 数组长度则不带环 * len 数组的长度 */ LinkList create_list(int *a, int pos, int len) { LinkedNode *temp = NULL; int i = 0; LinkedNode *record = NULL; LinkedNode *list_head = NULL; LinkedNode *p = NULL; if(a == NULL) { return NULL; } if(pos == 0 || pos > len) { record = NULL; } list_head = (LinkedNode*)malloc(sizeof(LinkedNode)); list_head->data = a[0]; list_head->next = NULL; temp = list_head; for(i = 1; i < len; i++) { while(temp->next != NULL) { temp = temp->next; } p = (LinkedNode *)malloc(sizeof(LinkedNode)); p->data = a[i]; p->next = NULL; temp->next = p; if((i + 1) == pos) { record = p; } } temp = list_head; while(temp->next != NULL) { temp = temp->next; } temp->next = record; return list_head; } /*判断单链表是否带环*/ int is_exist_loop(LinkList list) { int result = -1; LinkedNode *one_step = NULL; LinkedNode *two_step = NULL; one_step = list; two_step = list; while(two_step != NULL && two_step->next != NULL) { one_step = one_step->next; two_step = two_step->next->next; if(one_step == two_step) { result = 0; break; } } return result; }