Circular linked list C++ - c++

I'm trying to create a queue using a circular linked list. I just took my existing linked list implementation (which already works) and changed where the nodes pointed but it doesn't seem to be that straightforward. I'm sure it's one small thing that I'm overlooking.
void enqueue(int q){
newNode=new node;
newNode->info = q;
newNode->link = first;
if(first->link==first){
first = last = newNode;
last->link=first;
}
else{
last->link = newNode;
last= newNode;
last->link = first;
}
}
int dequeue(){
int x;
if(first->link==first){
cout <<"The Queue is empty" <<endl;
return 0;
}
else{
dummy=first;
x=dummy->info;
first=first->link;
delete(dummy);
return(x);
}
}

I converted this to a class. For a circular list class, only a pointer to last node is needed, as first = last->next. Since no dummy node is used, an empty list is normally indicated by last == NULL;
#include<iostream>
class circq
{
typedef struct node_
{
struct node_ *next;
int info;
}node;
node *last; // ptr to last node of list
public:
circq() // constructor
{
last = NULL; // reset last
}
bool isempty()
{
return last == NULL;
}
void enqueue(int q)
{
node *newNode=new node; // new node
newNode->info = q;
if(last == NULL){ // if empty list
last = newNode; // create single node list
newNode->next = newNode;
return;
} // else
newNode->next = last->next; // append node to end list
last->next = newNode;
last = newNode;
}
int dequeue()
{
if(last == NULL){ // check for empty list
return 0;
}
node *first = last->next; // set ptr to first node
int x = first->info; // set return value
if(last->next == last) // if single node
last = NULL; // set list to empty
else // else
last->next = first->next; // advance first to next node
delete first; // delete node
return x;
}
~circq() // destructor
{
while(!isempty())
dequeue();
}
};
int main() // test circq
{
circq cq;
cq.enqueue(0);
cq.enqueue(1);
cq.enqueue(2);
cq.enqueue(3);
while(!cq.isempty())
std::cout << cq.dequeue() << std::endl;
return 0;
}

Related

Linked List: Moving a Node to Start of the Linked List(C++)

The question is to find the key in a linked list and if it is present then move the node containing key to the front
struct Node {
int data;
Node *next;
Node(int data, Node *next_node) {
this->data = data;
this->next = next_node;
}
};
void display(Node *head) {
Node *temp_head = head;
while(temp_head != NULL) {
std::cout << temp_head->data << " ";
temp_head = temp_head->next;
}
std::cout << '\n';
}
bool improvedSearch(Node *head, int key) {
Node *previous = NULL, *current = head;
while(current != NULL) {
if(current->data == key) {
if(previous == NULL) {
return true;
}
previous->next = current->next;
current->next = head;
head = current;
display(head); /////
return true;
}
previous = current;
current = current->next;
}
return false;
}
int main() {
Node e(5, NULL);
Node d(4, &e);
Node c(3, &d);
Node b(2, &c);
Node a(1, &b);
Node *head = &a;
improvedSearch(head, 3);
display(head); /////
return 0;
}
When I call display inside the improvedSearch(head, 3) it shows the output "3 1 2 4 5" but when I call the display inside main function the output is "1 2 4 5". It seems like link to node containing 3 gets lost. Why is this happening?
In improvedSearch(), you are passing in the head parameter by value, so a copy of the caller's head is made, and any new value assigned to the head parameter by improvedSearch() will be only to that copy and not reflected back to the caller. But, improvedSearch() still modifies the contents of the list, and upon exit the caller's head is still pointing at the old head node which is no longer the new head node, which is why it appears a node was lost.
To fix this, pass in the head parameter by reference instead:
bool improvedSearch(Node* &head, int key)

Why it is printing only 1st value of doubly linked list and than my program is crashing

I am trying to create a doubly linked list and then printing its value but the output is showing only first value and then the whole program is crashing.
I can't understand where is the problem in the code .
Input
3
1 2 3
Expected output
1 2 3
current output
1
#include<iostream>
#include<stdlib.h>
using namespace std;
class node //declation of node
{
public:
int data;
node *next;
node *prev;
};
node *makenode(node *head,int val) //function to create node
{
node *newnode=new node;
node *temp;
newnode->data=val;
newnode->next=0;
newnode->prev=0;
if(head==0) temp=head=newnode;
else
{
temp->next=newnode;
newnode->prev=temp;
temp=newnode;
}
return head;
}
void display(node *head) //display function
{
system("cls"); //clearing output screen
while(head!=0)
{
cout<<head->data<<" ";
head=head->next;
}
}
int main()
{
node *head;
head=0;
int val;
int s; //size of list
cout<<"ENTER THE SIZE OF LIST";
cin>>s;
system("cls");
for(int i=0;i<s;i++)
{
cout<<"ENTER THE "<<i+1<<" VALUE\n";
cin>>val;
head=makenode(head,val); //calling makenode and putting value
}
display(head); //printing value
return 0;
}
node *makenode(node *head,int val) //function to create node
{
node *newnode=new node;
node *temp; // #1
newnode->data=val;
newnode->next=0;
newnode->prev=0;
if(head==0) temp=head=newnode;
else
{
temp->next=newnode; // #2
Between the lines marked #1 and #2 above, what exactly is setting the variable temp to point to an actual node rather than pointing to some arbitrary memory address?
"Nothing", I hear you say? Well, that would be a problem :-)
In more detail, the line:
node *temp;
will set temp to point to some "random" location and, unless your list is currently empty, nothing will change that before you attempt to execute:
temp->next = newnode;
In other words, it will use a very-likely invalid pointer value and crash if you're lucky. If you're unlucky, it won't crash but will instead exhibit some strange behaviour at some point after that.
If you're not worried about the order in the list, this could be fixed by just always inserting at the head, with something like:
node *makenode(node *head, int val) {
node *newnode = new node;
newnode->data = val;
if (head == 0) { // probably should use nullptr rather than 0.
newnode->next = 0;
newnode->prev = 0;
} else {
newnode->next = head->next;
newnode->prev = 0;
}
head = newnode;
return head;
}
If you are concerned about order, you have to find out where the new node should go, based on the value, such as with:
node *makenode(node *head, int val) {
node *newnode = new node;
newnode->data = val;
// Special case for empty list, just make new list.
if (head == 0) { // probably should use nullptr rather than 0.
newnode->next = 0;
newnode->prev = 0;
head = newnode;
return head;
}
// Special case for insertion before head.
if (head->data > val) {
newnode->next = head->next;
newnode->prev = 0;
head = newnode;
return head;
}
// Otherwise find node you can insert after, and act on it.
// Checknode will end up as first node where next is greater than
// or equal to insertion value, or the last node if it's greater
// than all current items.
node *checknode = head;
while (checknode->next != 0 && (checknode->next->data < val) {
checknode = checknode->next;
}
// Then it's just a matter of adjusting three or four pointers
// to insert (three if inserting after current last element).
newnode->next = checknode->next;
newnode->prev = checknode;
if (checknode->next != 0) {
checknode->next->prev = newnode;
}
checknode->next = newnode;
return head;
}
You aren't actually linking anything together. This line: if(head==0) temp=head=newnode; is the only reason your linked list contains a value at all. The very first value sets head equal to it and when you print head you get that value. In order to properly do a linked list you need a head and tail pointer. The head points to the first element in the list and the tail points to the last. When you add an element to the end of the list you use tail to find the last element and link to it. It is easiest to make Linked List a class where you can encapsulate head and tail:
struct Node {
public:
int data;
node *next;
node *prev;
Node(int data) : data(data), next(nullptr), prev(nullptr) {} // constructor
};
class LinkedList {
private:
Node* head;
Node* tail;
public:
LinkedList() { head = tail = nullptr; }
// This function adds a node to the end of the linked list
void add(int data) {
Node* newNode = new Node(data);
if (head == nullptr) { // the list is empty
head = newNode;
tail = newNode;
}
else { // the list is not empty
tail->next = newNode; // point the last element to the new node
newNode->prev = tail; // point the new element to the prev
tail = tail->next; // point the tail to the new node
}
}
};
int main() {
LinkedList lList;
lList.add(1);
lList.add(2);
// etc...
return 0;
}

Link list Adding CPP

I am implementing a link list with cpp,what is wrong with the following code?
Every time i step into the function---AddToTail, the "list" can't get correct value. It changes it value to the new constructed node.
#include <iostream>
using namespace std;
struct Node
{
int value;
Node * next;
};
void AddToTail(Node* &list, int value)
{
Node newnode;
newnode.value = value;
newnode.next = NULL;
if (list == NULL)
list = &newnode;
else
{
Node * list1 = list;
while (list1->next != NULL)
{
list1 = list1->next;
}
list1->next = &newnode;
int a = 1;
}
}
int main()
{
Node *list=NULL;
AddToTail(list, 1);
AddToTail(list, 2);
AddToTail(list, 3);
while (list->next != NULL)
{
cout << list->value << endl;
list = list->next;
}
system("pause");
}
void AddToTail(Node* &list, int value)
{
Node newnode;
// Set up fields of newnode.
// Store address of newnode into some other data structure.
}
This is your issue. You are creating a node on the stack and this node will go out of scope at the end of the function. The reason it seems to be interfering with later node creations is because re-entering the function will almost certainly create newnode at exactly the same address as in the previous call.
If you want objects to survive function scope, you're going to need to allocate them dynamically, something like:
void AddToTail (Node *&list, int value) {
Node *newnode = new Node(); // create on heap.
newnode->value = value; // set up node.
newnode->next = nullptr;
if (list == nullptr) { // list empty,
list = newnode; // just create.
return;
}
Node *lastNode = list; // find last item.
while (lastNode->next != nullptr)
lastNode = lastNode->next;
lastNode->next = newnode; // append to that.
}

Sorted queue linked list c++

I need to make a queue linked list in which the first node always has the smallest value , so it needs to be sorted , I have written this code :
#include <iostream>
using namespace std;
struct Node
{
int key;
Node *link;
};
class qlinkedlist
{
private:
Node *head;
Node *tail;
Node *curr;
Node *prev;
int count;
public:
void Enqueue(int value)
{
Node *newnode = new Node;
newnode -> key = value;
newnode -> link = NULL;
if(head==NULL)
{
head=tail=newnode;
count++;
}
else if(newnode->key < head->key)
{
newnode -> link = head;
head = newnode;
count++;
}
else
{
prev=head;
curr=head->link;
while(curr != NULL)
{
if(newnode->key < curr->key)
{
prev->link = newnode;
newnode->link = curr;
count++;
}
else
{
prev = curr;
curr = curr ->link;
}
}
}
}
void Dequeue()
{
if(head==NULL)
{
cout<< "Queue is empty" << endl;
}
else
{
curr = head;
head = head -> link;
delete curr;
count--;
}
}
void print()
{
curr = head;
while (curr!=NULL)
{
cout << curr -> key << endl;
curr = curr -> link;
}
}
};
void main()
{
qlinkedlist obj;
obj.Enqueue(5);
obj.Enqueue(4);
obj.Enqueue(3);
obj.Enqueue(2);
obj.Enqueue(1);
obj.print();
}
problem is it works only if I add nodes in the above order , for example if I try to add the 3 then 2 then 5 it does not work , what's wrong with the code ?
Thank you
Because if you try to add an element that is bigger than everything you have in the list, it will never pass your only condition to add a node: if(newnode->key < curr->key). Try this instead:
while(curr != NULL && newnode->key > curr->key)
{
prev = curr;
curr = curr ->link;
}
prev->link = newnode;
newnode->link = curr;
count++;
This way, you go through the linked list until you find the right spot, then add the new node even if you get to the end (curr==NULL).

LinkedList/Stack/Queue - Help with Dequeuing

I had to write a linked list, then turn it into a dynamic Stack, then turn that into a dynamic Queue. Well everything seems to work except the "dequeuing", right as the programs about to finish, it gives me an error: "An unhandled win32 exception occured in LinkedList_Stack_BNS11.exe [4972].".
I'm only assuming it's the dequeuing, because as I step through and/or run the program, it runs smoothly up till that part, so maybe I sent one of the pointers wrong or something?
Output:
Enquing 5 items....
// Finsihes
The values in the queue were (Dequeuing):
0
1
2
// Correct number in que but...
//Program gives that error right here. When it should finish and close.
If I included too much code let me know and I'll chop it down to just the "Dequeuing" (Which is in the very middle of all the stuff below)
Thanks in advance for the help!! I'm just not seeing what I did wrong. Thinking it maybe has something to do with where "head" is pointing? Idk.
Header File:
class NumberList
{
private:
//
struct ListNode
{
int value; // Value in this node
struct ListNode *next; // Pointer to the next node
};
ListNode *head; // List head pointer
ListNode *rear;
public:
//Constructor
NumberList()
{ head = NULL; rear = NULL; }
//Destructor
~NumberList();
//Stack operations
bool isEmpty();
//Queue operations
void enqueue(int);
void dequeue(int &);
};
#endif
List_Stack_Queue.cpp:
bool NumberList::isEmpty()
{
bool status;
if(!head)
status = true;
else
status = false;
return status;
}
void NumberList::enqueue(int num)
{
ListNode *newNode; // Point to a new node
// Allocate a new node and store num there.
newNode = new ListNode;
newNode->value = num;
//If there are no nodes in the list
// make newNode the first node.
if(isEmpty())
{
head = newNode;
rear = head;
//newNode->next = NULL;
}
else
{
rear->next = newNode;
rear = rear->next;
//newNode->next = head;
//head = newNode;
}
}
void NumberList::dequeue(int &num)
{
ListNode *temp;
if(isEmpty())
cout << "The queue is empty.\n";
else
{
num = head->value;
temp = head;
head = head->next;
delete temp;
}
}
MAIN:
const int MAX_VALUES = 3;
// Create a DynIntQueue object.
NumberList iQueue;
// Enqueue a series of numbers.
cout << "Enqueuing " << MAX_VALUES << " items...\n";
for (int x = 0; x < MAX_VALUES; x++)
iQueue.enqueue(x);
cout << endl;
//Dequeue and retrieve all numbers in the queue
cout << "The values in the queue were (Dequeuing):\n";
while(!iQueue.isEmpty())
{
int value;
iQueue.dequeue(value);
cout << value << endl;
}
return 0;
Last nodes's next element should be set to NULL in a linked list. So,
void NumberList::enqueue(int num)
{
// ...
if(isEmpty())
{
head = newNode;
head->next = NULL;
rear = head;
}
else
{
rear->next = newNode;
rear = rear->next;
rear->next = NULL; // Pointing the next node element to null.
}
}
To, me it seems some thing is wrong with Numberlist::isEmpty(); member function. How you are deciding whether the list is empty or not ? Show the definition of it.