判断list是否存在环

给出如下结构:
struct node
{
struct *next;
};
typedef stuct node Node;
 
bool getCycle(){
Node* temp1 = head;//(假设head就是这个链表的头)
Node* temp2 = head;
while(head->next!=NULL)
{
temp1 = temp1->next;//步长为1
temp2 = temp2->next->next;//步长为2
if(temp1 == temp2)
return ture;
head=head->next;
}
return false;

}

写一段代码判断一个单向链表中是否有环。

原理:

设置两个指针,开始都指向链表头,然后其中一个指针每次向前走一步,另一个指针每次向前走两步,如果快的遇到NULL了,证明该链表中没有环,如果有环,快的指针每次都要比慢的多走一步,最终两个指针会相遇,(注意:这里快指针不会跳过慢指针而不相遇,因为它每次都只比慢指针多走一个单位)
bool judge(list *head){if(head == NULL){return false;//没有环}
list *pFast = head;
list *pSlow = head;
while(pFast-next != NULL && pFast-next-next != NULL){pFast = pFast-next-next;
pSlow = pSlow-next;


http://blog.csdn.net/guoyong10721073/article/details/8144401

多种思路:

http://blog.csdn.net/htyurencaotang/article/details/11481875

http://www.cnblogs.com/shuaiwhu/archive/2012/05/03/2480509.html

http://www.xuebuyuan.com/1570516.html

为啥步长是1?

http://blog.chinaunix.net/uid-21393885-id-88130.html

综合:http://blog.csdn.net/thefutureisour/article/details/8174313

http://www.cnblogs.com/zhyg6516/archive/2011/03/29/1998831.html


题目描述

一个链表中包含环,请找出该链表的环的入口结点。
//第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,
//p2每次走二步,直到p1==p2找到在环中的相汇点。
//第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,
//设环中有n个节点,p2比p1多走一圈有2x=n+x; n=x;可以看出p1实际走了一个环的步数,
//再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
   if(pHead == NULL || pHead->next == NULL)
            return NULL;
        ListNode* p1 = pHead;
        ListNode* p2 = pHead;
        while(p2 != NULL && p2->next != NULL ){
            p1 = p1->next;
            p2 = p2->next->next;
            if(p1 == p2){
                p2 = pHead;
                while(p1 != p2){
                    p1 = p1->next;
                    p2 = p2->next;
                }
                if(p1 == p2)
                    return p1;
            }
        }
        return NULL;
    }
};
















有向图是否存在可以通过深度优先搜索(DFS)来判断。 首先,我们需要定义一个visited数组来表示节点是否被访问过。初始时,visited数组的所有元素均设为未访问过。 然后,我们可以从图中的任意一个节点开始进行深度优先搜索。在深度优先搜索的过程中,每次访问一个节点时,首先将该节点的visited值设为正在访问,并将其所有的未访问的邻居节点递归调用DFS进行深度优先搜索。当递归调用DFS时,如果发现邻居节点已经被访问过且其visited值为正在访问,则说明存在。最后,在访问结束后,将节点的visited值设为已访问。 以下是用C语言实现的判断有向图是否存在的代码示例: ```c #include<stdio.h> #include<stdlib.h> #define SIZE 100 // 有向图的最大节点数 int visited[SIZE]; // 用于标记节点是否被访问过 struct Node { int value; struct Node* next; }; struct Graph { int num_nodes; struct Node** adj_list; }; struct Node* createNode(int value) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->value = value; newNode->next = NULL; return newNode; } void addEdge(struct Graph* graph, int src, int dest) { struct Node* newNode = createNode(dest); newNode->next = graph->adj_list[src]; graph->adj_list[src] = newNode; } int hasCycleUtil(struct Graph* graph, int node, int* visited) { visited[node] = 1; // 将节点标记为正在访问 struct Node* neighbor = graph->adj_list[node]; while (neighbor != NULL) { if (visited[neighbor->value] == 1) { return 1; // 如果邻居节点已经被访问过,则存在 } if (visited[neighbor->value] == 0 && hasCycleUtil(graph, neighbor->value, visited)) { return 1; // 递归调用DFS,判断邻居节点是否存在 } neighbor = neighbor->next; } visited[node] = 2; // 将节点标记为已访问 return 0; } int hasCycle(struct Graph* graph) { int i; for (i = 0; i < graph->num_nodes; i++) { visited[i] = 0; // 初始化visited数组 } for (i = 0; i < graph->num_nodes; i++) { if (visited[i] == 0 && hasCycleUtil(graph, i, visited)==1) { return 1; // 从每个未访问的节点开始进行DFS,如果存在则返回1 } } return 0; } int main() { int numNodes, numEdges, i; printf("请输入有向图的节点数和边数:"); scanf("%d%d", &numNodes, &numEdges); struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph)); graph->num_nodes = numNodes; graph->adj_list = (struct Node**)malloc(numNodes * sizeof(struct Node*)); for (i = 0; i < numNodes; i++) { graph->adj_list[i] = NULL; } for (i = 0; i < numEdges; i++) { int src, dest; printf("请输入第%d条边的起点和终点:", i + 1); scanf("%d%d", &src, &dest); addEdge(graph, src, dest); } if (hasCycle(graph)) { printf("有向图存在\n"); } else { printf("有向图不存在\n"); } return 0; } ``` 以上是通过DFS算法判断有向图是否存在的C语言代码。代码的核心是hasCycleUtil函数,利用visited数组来标记节点的访问状态,通过递归调用DFS,判断邻居节点是否被访问过且visited值为正在访问,从而判断是否存在
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值