Skip to content

Instantly share code, notes, and snippets.

@makokal
Created February 6, 2012 18:24
Show Gist options
  • Save makokal/1753877 to your computer and use it in GitHub Desktop.
Save makokal/1753877 to your computer and use it in GitHub Desktop.
Simple cycle check in singly linked list (was part of SDE code interview)
/**
* Simple Singly Linked List
* Demonstrating check for cycles by remembering all visited nodes
*
* Using BOOST::Unordered_map as a hash table implementation
*
* \author Billy Okal
*/
#include <iostream>
#include <boost/unordered_map.hpp>
using namespace std;
// A simple singly linked list node
class SNode
{
public:
SNode() { next = NULL; }
virtual ~SNode() {}
void SetData(int aData) { data = aData; }
void SetNext(SNode *aNext) { next = aNext; }
int Data() { return data; }
SNode* Next() { return next; }
private:
int data;
SNode* next;
};
// A simple singly linked list
class SList
{
public:
SList() { head = NULL; }
virtual ~SList() {}
// print the list
void Print()
{
SNode *tmp = head;
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
if ( tmp->Next() == NULL ) {
cout << tmp->Data();
cout << " -> ";
cout << "NULL" << endl;
}
else {
do {
cout << tmp->Data();
cout << " -> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
// append a member to the list
void Append(int data)
{
SNode* newNode = new SNode();
newNode->SetData(data);
newNode->SetNext(NULL);
SNode* tmp = head;
if ( tmp != NULL ) {
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
tmp->SetNext(newNode);
}
else {
head = newNode;
}
}
void MakeCycle()
{
// make a simple cycle
SNode* tmp = head;
// move till the end and connect to the first
if ( tmp != NULL ) {
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
tmp->SetNext(head);
}
else {}
}
SNode* Begin() const { return head; }
private:
SNode* head;
};
//overload hash_values
bool operator==(SNode n1, SNode n2)
{
return n1.Next() == n2.Next();
}
std::size_t hash_value(SNode n) {
std::size_t seed = 0;
boost::hash_combine(seed, n.Data());
boost::hash_combine(seed, n.Data());
return seed;
}
// Check for cycles in a singly linked list
int CheckCycles(SList _list)
{
SNode* node = _list.Begin();
int cycle = 0;
boost::unordered_map<SNode,int> hs;
boost::unordered_map<SNode,int>::iterator it;
while (node != NULL) {
it = hs.find( (*node) );
if(it == hs.end() ) {
hs.insert(boost::unordered_map<SNode,int>::value_type((*node),node->Data()));
node = node->Next();
}
else {
cycle = 1;
break;
}
}
return cycle;
}
int main(int argc, char** argv)
{
//make a list and populate it
SList no_cycle_list;
no_cycle_list.Append(1);
no_cycle_list.Append(2);
no_cycle_list.Append(3);
no_cycle_list.Append(4);
no_cycle_list.Append(5);
no_cycle_list.Print();
cout << "Cycle check before inserting cycle " << CheckCycles(no_cycle_list) << endl;
// make a cycle
no_cycle_list.MakeCycle();
cout << "Cycle check after inserting cycle " << CheckCycles(no_cycle_list) << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment