技术文摘
五个C++中检测链表循环的解决办法
2024-12-31 07:35:22 小编
五个 C++ 中检测链表循环的解决办法
在 C++ 编程中,链表是一种常见的数据结构。然而,链表可能会出现循环的情况,这会导致一些意想不到的错误。下面将介绍五个检测链表循环的有效解决办法。
方法一:快慢指针法
这是一种常见且高效的方法。设置两个指针,一个快指针每次移动两步,一个慢指针每次移动一步。如果链表存在循环,快指针最终会追上慢指针。
bool hasCycle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
return true;
}
}
return false;
}
方法二:哈希表法
遍历链表,将每个节点的地址存储在哈希表中。如果遇到已经在哈希表中的地址,说明存在循环。
bool hasCycle(ListNode* head) {
unordered_set<ListNode*> visited;
while (head) {
if (visited.count(head)) {
return true;
}
visited.insert(head);
head = head->next;
}
return false;
}
方法三:标记法
为链表节点添加一个额外的标记字段,在遍历过程中标记已访问的节点。再次遇到标记过的节点则表示存在循环。
struct ListNode {
int val;
bool visited;
ListNode* next;
ListNode(int x) : val(x), visited(false), next(NULL) {}
};
bool hasCycle(ListNode* head) {
while (head) {
if (head->visited) {
return true;
}
head->visited = true;
head = head->next;
}
return false;
}
方法四:反转链表法
尝试反转链表,如果反转过程中遇到已经反转过的节点,说明存在循环。但这种方法可能会改变链表的结构。
bool hasCycle(ListNode* head) {
ListNode* prev = NULL;
ListNode* curr = head;
while (curr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
if (curr == head) {
return true;
}
}
return false;
}
方法五:利用节点值
假设节点值可以修改,将遍历过的节点值修改为一个特殊值。再次遇到该特殊值则说明存在循环。
bool hasCycle(ListNode* head) {
while (head) {
if (head->val == -1) {
return true;
}
head->val = -1;
head = head->next;
}
return false;
}
以上就是五个在 C++ 中检测链表循环的解决办法,在实际应用中,可以根据具体情况选择合适的方法。
- MySQL 排序底层原理剖析
- 解决 Oracle 客户端连接报错 ORA-12545 的办法
- MySQL 多表查询及事务处理
- MySQL 用户权限查看与管理方法全面解析
- Oracle 导入 txt 文件数据的详细解析
- Oracle 密码永不过期的设置方法
- Oracle 借助 dblink 完成跨库访问的实例代码
- Oracle 表空间的创建、运用、重命名及删除之法
- MySQL 双主复制服务搭建与 HAProxy 负载均衡过程详述
- MySQL 8.0.26 升级至 32 版本查询数据为空的解决办法
- MySQL 生产环境 CPU 使用率过高的排查及解决办法
- ORA-01034: ORACLE not available 报错的解决之文
- MySQL 表的四种分区类型全解析
- Oracle 新用户创建、权限配置与查询语句
- Oracle 用户密码过期后如何设置永不过期