diff --git a/doubly_linked_list.cpp b/doubly_linked_list.cpp new file mode 100644 index 00000000..67f1d6fb --- /dev/null +++ b/doubly_linked_list.cpp @@ -0,0 +1,270 @@ +#include +#include +using namespace std; + +class Node { + + public: + int data; + Node* next; + + + Node(int data) { + this -> data = data; + this -> next = NULL; + } + + + ~Node() { + int value = this -> data; + + if(this->next != NULL) { + delete next; + this->next = NULL; + } + cout << " memory is free for node with data " << value << endl; + } + +}; + +void insertAtHead(Node* &head, int d) { + + + Node* temp = new Node(d); + temp -> next = head; + head = temp; +} + +void insertAtTail(Node* &tail, int d) { + + Node* temp = new Node(d); + tail -> next = temp; + tail = temp; +} + +void print(Node* &head) { + + if(head == NULL) { + cout << "List is empty "<< endl; + return ; + } + Node* temp = head; + + while(temp != NULL ) { + cout << temp -> data << " "; + temp = temp -> next; + } + cout << endl; +} + +void insertAtPosition(Node* &tail, Node* & head, int position, int d) { + + + + if(position == 1) { + insertAtHead(head, d); + return; + } + + Node* temp = head; + int cnt = 1; + + while(cnt < position-1) { + temp = temp->next; + cnt++; + } + + if(temp -> next == NULL) { + insertAtTail(tail,d); + return ; + } + + + Node* nodeToInsert = new Node(d); + + nodeToInsert -> next = temp -> next; + + temp -> next = nodeToInsert; +} + +void deleteNode(int position, Node* & head) { + + + if(position == 1) { + Node* temp = head; + head = head -> next; + + temp -> next = NULL; + delete temp; + } + else + { + + Node* curr = head; + Node* prev = NULL; + + int cnt = 1; + while(cnt < position) { + prev = curr; + curr = curr -> next; + cnt++; + } + + prev -> next = curr -> next; + curr -> next = NULL; + delete curr; + + } +} + +bool isCircularList(Node* head) { + + if(head == NULL) { + return true; + } + + Node* temp = head -> next; + while(temp != NULL && temp != head ) { + temp = temp -> next; + } + + if(temp == head ) { + return true; + } + + return false; +} + + +bool detectLoop(Node* head) { + + if(head == NULL) + return false; + + map visited; + + Node* temp = head; + + while(temp !=NULL) { + + + if(visited[temp] == true) { + cout << "Present on element " << temp->data << endl; + return true; + } + + visited[temp] = true; + temp = temp -> next; + + } + return false; + +} + +Node* floydDetectLoop(Node* head) { + + if(head == NULL) + return NULL; + + Node* slow = head; + Node* fast = head; + + while(slow != NULL && fast !=NULL) { + + fast = fast -> next; + if(fast != NULL) { + fast = fast -> next; + } + + slow = slow -> next; + + if(slow == fast) { + cout << "present at " << slow -> data << endl; + return slow; + } + } + + return NULL; + +} + +Node* getStartingNode(Node* head) { + + if(head == NULL) + return NULL; + + Node* intersection = floydDetectLoop(head); + Node* slow = head; + + while(slow != intersection) { + slow = slow -> next; + intersection = intersection -> next; + } + + return slow; + +} + +void removeLoop(Node* head) { + + if( head == NULL) + return; + + Node* startOfLoop = getStartingNode(head); + Node* temp = startOfLoop; + + while(temp -> next != startOfLoop) { + temp = temp -> next; + } + + temp -> next = NULL; + +} + + +int main() { + + + Node* node1 = new Node(10); + + + + Node* head = node1; + Node* tail = node1; + + + insertAtTail(tail, 12); + + + + insertAtTail(tail, 15); + + + insertAtPosition(tail,head, 4, 22); + + + + tail -> next = head ->next; + + cout << "head " << head -> data << endl; + cout << "tail " << tail -> data << endl; + + + if(floydDetectLoop(head) != NULL) { + cout << "Cycle is present " << endl; + } + else + { + cout << "no cycle" << endl; + } + + Node* loop = getStartingNode(head); + + cout << "loop starts at " << loop -> data << endl; + + removeLoop(head); + print(head); + + + return 0; +}