algos/cs/graph/
floyd_cycle.rs1use std::cell::RefCell;
50use std::rc::Rc;
51
52#[derive(Debug)]
56pub struct ListNode<T> {
57 pub val: T,
58 pub next: Option<Rc<RefCell<ListNode<T>>>>,
59}
60
61impl<T> ListNode<T> {
62 pub fn new(val: T) -> Self {
64 ListNode { val, next: None }
65 }
66}
67
68pub fn has_cycle<T>(head: &Option<Rc<RefCell<ListNode<T>>>>) -> bool {
72 let mut slow = head.clone();
74 let mut fast = head.clone();
75
76 while let Some(f) = fast {
77 let next_fast = f.borrow().next.clone();
79 if let Some(f2) = next_fast {
80 fast = f2.borrow().next.clone();
82 } else {
83 return false;
85 }
86
87 if let Some(s) = slow.clone() {
89 slow = s.borrow().next.clone();
90 }
91
92 if let (Some(sf), Some(ff)) = (slow.clone(), fast.clone()) {
94 if Rc::ptr_eq(&sf, &ff) {
95 return true;
96 }
97 } else {
98 return false;
99 }
100 }
101 false
102}
103
104pub fn find_cycle_start<T>(
112 head: &Option<Rc<RefCell<ListNode<T>>>>,
113) -> Option<Rc<RefCell<ListNode<T>>>> {
114 if head.is_none() {
116 return None;
117 }
118 let mut slow = head.clone();
119 let mut fast = head.clone();
120 let mut intersection: Option<Rc<RefCell<ListNode<T>>>> = None;
121
122 while let Some(f) = fast {
124 let next_fast = f.borrow().next.clone();
125 if let Some(f2) = next_fast {
126 fast = f2.borrow().next.clone();
127 } else {
128 return None; }
130
131 if let Some(s) = slow.clone() {
132 slow = s.borrow().next.clone();
133 }
134
135 if let (Some(sf), Some(ff)) = (slow.clone(), fast.clone()) {
136 if Rc::ptr_eq(&sf, &ff) {
137 intersection = Some(sf);
138 break;
139 }
140 } else {
141 return None;
142 }
143 }
144
145 intersection.as_ref()?;
147
148 let mut ptr1 = head.clone();
150 let mut ptr2 = intersection;
151 while let (Some(p1), Some(p2)) = (ptr1, ptr2) {
152 if Rc::ptr_eq(&p1, &p2) {
153 return Some(p1);
154 }
155 ptr1 = p1.borrow().next.clone();
156 ptr2 = p2.borrow().next.clone();
157 }
158 None
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164
165 #[test]
166 fn test_empty_list() {
167 assert_eq!(has_cycle::<i32>(&None), false);
168 assert!(find_cycle_start::<i32>(&None).is_none());
169 }
170
171 #[test]
172 fn test_single_node_no_cycle() {
173 let n1 = Rc::new(RefCell::new(ListNode::new(42)));
174 let head = Some(n1.clone());
175 assert_eq!(has_cycle(&head), false);
176 assert!(find_cycle_start(&head).is_none());
177 }
178
179 #[test]
180 fn test_two_nodes_no_cycle() {
181 let n1 = Rc::new(RefCell::new(ListNode::new(1)));
182 let n2 = Rc::new(RefCell::new(ListNode::new(2)));
183 n1.borrow_mut().next = Some(n2.clone());
184
185 let head = Some(n1.clone());
186 assert_eq!(has_cycle(&head), false);
187 assert!(find_cycle_start(&head).is_none());
188 }
189
190 #[test]
191 fn test_small_cycle() {
192 let n1 = Rc::new(RefCell::new(ListNode::new(1)));
193 let n2 = Rc::new(RefCell::new(ListNode::new(2)));
194 let n3 = Rc::new(RefCell::new(ListNode::new(3)));
195
196 n1.borrow_mut().next = Some(n2.clone());
198 n2.borrow_mut().next = Some(n3.clone());
199 n3.borrow_mut().next = Some(n2.clone());
200
201 let head = Some(n1.clone());
202 assert_eq!(has_cycle(&head), true);
203
204 let start = find_cycle_start(&head).unwrap();
205 assert!(Rc::ptr_eq(&start, &n2));
206 }
207
208 #[test]
209 fn test_longer_cycle() {
210 let n1 = Rc::new(RefCell::new(ListNode::new(1)));
213 let n2 = Rc::new(RefCell::new(ListNode::new(2)));
214 let n3 = Rc::new(RefCell::new(ListNode::new(3)));
215 let n4 = Rc::new(RefCell::new(ListNode::new(4)));
216 let n5 = Rc::new(RefCell::new(ListNode::new(5)));
217
218 n1.borrow_mut().next = Some(n2.clone());
219 n2.borrow_mut().next = Some(n3.clone());
220 n3.borrow_mut().next = Some(n4.clone());
221 n4.borrow_mut().next = Some(n5.clone());
222
223 n5.borrow_mut().next = Some(n3.clone());
225
226 let head = Some(n1.clone());
227
228 assert_eq!(has_cycle(&head), true);
229 let start = find_cycle_start(&head).unwrap();
230 assert!(Rc::ptr_eq(&start, &n3));
231 }
232
233 #[test]
234 fn test_no_cycle_long_list() {
235 let n1 = Rc::new(RefCell::new(ListNode::new(1)));
237 let n2 = Rc::new(RefCell::new(ListNode::new(2)));
238 let n3 = Rc::new(RefCell::new(ListNode::new(3)));
239 let n4 = Rc::new(RefCell::new(ListNode::new(4)));
240 let n5 = Rc::new(RefCell::new(ListNode::new(5)));
241
242 n1.borrow_mut().next = Some(n2.clone());
243 n2.borrow_mut().next = Some(n3.clone());
244 n3.borrow_mut().next = Some(n4.clone());
245 n4.borrow_mut().next = Some(n5.clone());
246
247 let head = Some(n1.clone());
248 assert_eq!(has_cycle(&head), false);
249 assert!(find_cycle_start(&head).is_none());
250 }
251}