This is my revised code which uses smart pointers. I also coded another direct way of testing for cycles by seeing if the pointers repeat. Does this seem ok? Thanks a lot for your feedback.
#include <cstdio>
#include <unordered_set>
#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
struct Node
{
int data;
std::shared_ptr<Node> next;
};
// A fast pointer and a slow pointer are both initiated at the head.
// Circular if the slow pointer is ever ahead of the fast pointer.
bool isCycle(std::shared_ptr<Node> head)
{
auto slowPointer = head;
auto fastPointer = head;
while(fastPointer && fastPointer->next && fastPointer->next->next)
{
slowPointer = slowPointer->next;
fastPointer = fastPointer->next->next;
if(fastPointer == slowPointer || fastPointer->next == slowPointer)
return true;
}
return false;
}
// A direct algorithm to tell if a cycle is present by seeing if a pointer address repeats.
bool isCycleDirect(std::shared_ptr<Node> head)
{
std::unordered_set<std::shared_ptr<Node>> nodePointers;
while(head)
{
// If trying to insert something already inserted, then must contain cycles.
if(nodePointers.find(head) != nodePointers.end())
return true;
nodePointers.insert(head);
head = head->next;
}
return false;
}
// Test against the expected results.
void testCycle(std::shared_ptr<Node> head, bool expected)
{
printf(isCycle(head) == expected ? "Results as expected\n" : "This test case failed\n");
}
// Set up tests for small numbers of nodes
void smallTests()
{
std::shared_ptr<Node> emptyList;
testCycle(emptyList, false);
std::shared_ptr<Node> List1(new Node);
std::shared_ptr<Node>ListCircular2(new Node);
std::shared_ptr<Node>ListNonCircular2(new Node);
std::shared_ptr<Node>ListCircular3(new Node);
std::shared_ptr<Node>ListNonCircular3(new Node);
List1->next = nullptr;
List1->data = 1;
testCycle(List1, false);
ListCircular2 = List1;
ListCircular2 -> next = ListCircular2;
testCycle(ListCircular2, true);
ListNonCircular2 = ListCircular2;
ListNonCircular2->next = std::shared_ptr<Node>(new Node);
ListNonCircular2->next->data = 2;
ListNonCircular2->next->next = nullptr;
testCycle(ListNonCircular2, false);
ListNonCircular3 = ListNonCircular2;
ListNonCircular3->next->next = std::shared_ptr<Node>(new Node);
ListNonCircular3->next->next->data = 3;
ListNonCircular3->next->next->next = nullptr;
testCycle(ListNonCircular3, false);
ListCircular3 = ListNonCircular3;
ListCircular3->next->next->next = ListCircular3;
testCycle(ListCircular3, true);
}
int main()
{
smallTests();
return 0;
}
Paul