Circular Single Linked List C++ Delete Problem - c++

I want to remove one node from a Circular Single Linked List and when i reach to the Cmd, it shows me an address (maybe) which is repeating infintely. Please help me or show me what is wrong. Here is the code in C++
using namespace std;
class Node{
private:
int data;
Node * next;
public:
void setdata(int s);
int getdata()
{
return data;
}
void setnext(Node * next_pointer);
Node * getnext();
};
void Node::setdata(int s){
data = s;
}
Node * Node::getnext(){
return this->next;
}
void Node::setnext(Node *next_node)
{
this->next = next_node;
}
class Circular{
private:
Node * first;
int sizen;
public:
Circular();
void append(int value);
void display();
Node * walk(int start, int die=3);
int remove_node(Node * prev_node);
int getsize();
Node * get_first();
void removing(int val);
};
Circular::Circular(){
first = 0;
sizen = 0;
}
void Circular::append(int val)
{
Node * new_node = new Node;
new_node -> setdata(val);
if(this->sizen == 0 )
{
//There is empty
this->first = new_node;
this->first -> setnext(this->first);
this->sizen = 1;
}
else
{
//It's not empty
Node *node = this->first;
while(node->getnext()!= this->first)
{
node = node->getnext();
}
node->setnext(new_node);
node->getnext() -> setnext(this->first);
this->sizen +=1;
}
}
void Circular::display()
{
Node *temp = this->first;
std::cout<<temp->getdata()<<" ";
temp = temp->getnext();
while(temp!=this->first)
{
std::cout<<temp->getdata()<<" ";
temp = temp->getnext();
}
}
void Circular::removing(int val)
{
Node *new_node = this->first, *d;
/*if(new_node->sizen==0)
return 0;
if(new_node->sizen==1 && new_node->getdata() == val)
{free(new_node);
return 0;
}*/
std::cout<<"Removing "<<val<<std::endl;
while((new_node->getnext())->getdata()!=val)
{
new_node = new_node->getnext();
}
if((new_node->getnext())->getdata()==val)
{
d = new_node->getnext();
new_node->getnext() ->setnext(d->getnext());
free(d);
}
}
int Circular::getsize(){
Node *temp = this->first;
int length = 0;
length++;
while(temp->getnext()!=this->first)
{
temp = temp->getnext();
length++;
}
return length;
}
int main(){
Circular l;
int i, n,k;
std::cout<<"How many participants do you want? ";
std::cin>>n;
std::cout<<"Which participant should be killed? (Kth)";
std:cin>>k;
for(i=1;i<=n;i++)
l.append(i);
l.display();
l.removing(2);
l.display();
}
And Here is where the problem gets me anxious:
void Circular::removing(int val)
{
Node *new_node = this->first, *d;
/*if(new_node->sizen==0)
return 0;
if(new_node->sizen==1 && new_node->getdata() == val)
{free(new_node);
return 0;
}*/
std::cout<<"Removing "<<val<<std::endl;
while((new_node->getnext())->getdata()!=val)
{
new_node = new_node->getnext();
}
if((new_node->getnext())->getdata()==val)
{
d = new_node->getnext();
new_node->getnext() ->setnext(d->getnext());
free(d);
}
}
I have no error and when I run the program, I want to remove the Second (2) node, but it shows me:
1 1114304 1114304 1114304 1114304 1114304 and so on.

Related

Binary Search Tree Deletion Problem When creating the Node class with left node first

I am creating a binary search tree in C++ using classes. When I write the left address first as in the example, deletion is not working correctly for random nodes.
Example:
class Node{
public:
int data;
Node* left;
Node* right;
Node(){ data=0; right=left=NULL;};
Node(int x){ data=x; right=left=NULL;};
bool is_leaf(){ return (left==NULL && right==NULL);
}
};
class BST{
private:
Node* root;
Node * _del(int x,Node* n);
void _insert_rec(int x,Node*n);
public:
BST(){ root=NULL; };
void insert_rec(int x);
void print();
void del(int x);
};
void BST::del(int x)
{
root = _del(x,root);
}
Node * BST::_del(int x,Node* n)
{
if(!n)
return NULL;
else
{
if(x<n->data)
n->left = _del(x,n->left);
else if(x>n->data)
n->right = _del(x,n->right);
else
{
if(n->is_leaf())
{
delete n;
return NULL;
}
else
{
if(!n->right)
{
delete n;
return n->left;
}
else if (!n->left)
{
delete n;
return n->right;
}
else
{
int enb = _max_value(n->left);
n->data = enb;
n->left = _del(enb,n->left);
}
}
}
}
return n;
}
void BST::insert_rec(int x)
{
root = _insert_rec(x,root);
}
Node * BST::_insert_rec(int x,Node* r)
{
if(!r)
return new Node(x);
else
{
if(x>r->data)
r->right = _insert_rec(x,r->right);
else
r->left = _insert_rec(x,r->left);
}
return r;
}
int main(int argc, char** argv)
{
BST *bst = new BST();
bst->insert_rec(50);
bst->insert_rec(100);
bst->insert_rec(20);
bst->insert_rec(10);
bst->insert_rec(70);
bst->print();
bst->del(100);
cout<<endl;
bst->print();
return 0;
}
When I try to delete 100 or 50, the code doesn't work.
If I change the Node class as below everything works fine:
class Node{
public:
int data;
Node* right; // Only changed the order of the addresses.
Node* left;
Node(){ data=0; right=left=NULL;};
Node(int x){ data=x; right=left=NULL;};
bool is_leaf(){ return (left==NULL && right==NULL);
}
};
Changed the order of the addresses. But I want to understand the reason behind this situation.
One problem is here
if(!n->right)
{
delete n;
return n->left;
}
You are deleting the pointer n and then dereferencing it. You should use a temporary variable
if(!n->right)
{
Node* tmp = n->left;
delete n;
return tmp;
}
With that change (in two places) it seems to work for me.

I am not getting how to concatenate two Linked List

I am not getting how to run the concatenate function using both Node and LinkedList as classes. If anyone knows how to do it, please let me know.
Here I have created two classes one for linked list and the former one for Node creation.
Using create function and passing array as Linked list input. Also, I am getting the headref using getHead() and getHead2() functions which give the starting pointer of first and second Linked List respectively.
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node(){
data=0;
next=NULL;
}
Node(int data){
this->data=data;
this->next=NULL;
}
};
class LL{
Node* first, *second;
public:
LL(){
first=second=NULL;
}
void create(int arr[], int n){
Node* t, *last;
first=new Node();
first->data= arr[0];
first->next=NULL;
last=first;
for(int i=1;i<n;i++){
t=new Node();
t->data=arr[i];
t->next=NULL;
last->next=t;
last=t;
}
}
void create2(int arr[], int n){
Node* t, *last;
second=new Node();
second->data= arr[0];
second->next=NULL;
last=second;
for(int i=1;i<n;i++){
t=new Node();
t->data=arr[i];
t->next=NULL;
last->next=t;
last=t;
}
}
Node* getHead(){
return first;
}
Node* getHead2(){
return second;
}
void display(Node* p){
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void concatLL(){
Node* p=first;
while(p->next){
p=p->next;
}
p->next=second;
second=NULL;
}
};
int main()
{
LL l,l2;
int arr[]={1,2,3,4,5,6,7};
int arr2[]={2,5,7,8,9};
int n=sizeof(arr)/sizeof(arr[0]);
int n2=sizeof(arr2)/sizeof(arr2[0]);
l.create(arr,n);
l2.create2(arr2,n2);
cout<<"Displaying first LL"<<endl;
l.display(l.getHead());
cout<<"Displaying second LL"<<endl;
l2.display(l2.getHead2());
cout<<"Displaying Linked list after concatination"<<endl;
l.concatLL();
l.display(l.getHead());
return 0;
}
p is equal to NULL when executing p->next=second; in concatLL() causing undefined behaviour since the while loop runs until p == NULL. You should use while(p->next) instead of while(p) and check that first is not a null pointer before.
A linked list is still a Node, and as others said, at the end of your while loop p is pointed to NULL. You can't NULL->second=second neither NULL=second, so change your while loop stop condition:
void concatLL(){
Node* p=first;
while(p->next){
p=p->next;
}
p->next=second;
second=NULL;
}
};
Here is my solution:
#include <iostream>
using namespace std;
struct Node {
Node* next;
int value;
Node(int value) {
this->value = value;
this->next = NULL;
}
Node(int n, int a[]) {
value = a[0];
next = NULL;
Node* p = this;
for (int i = 1; i < n; i++) {
p->next = new Node(a[i]);
p = p->next;
}
}
void concat(Node* head) {
Node* p = this;
while (p->next != NULL) {
p = p->next;
}
p->next = head;
}
void display() {
Node* current = this;
while (current != nullptr) {
cout << current->value << " ";
current = current->next;
}
cout << endl;
}
};
int main() {
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 6, 7, 8, 9, 10 };
Node* list1 = new Node(5, a);
Node* list2 = new Node(5, b);
list1->display();
list2->display();
list1->concat(list2);
list1->display();
return 0;
}

How to actually get the values to insert into this linked-list c++

So I wrote a function to have values insert into the linked list but now I'm having trouble successfully calling it from the main. Here's my code
class node
{
public:
int item; node* next;
node(int x, node* t)
{
item = x; next = t;
}
void insert(int n)
{
node *tmp = new node(n, next);
tmp -> item = n;
tmp->next = head;
head = tmp;
}
};
typedef node *link;
int main()
{
int i, N = 9, M = 5;
link t = new node(1, 0); t->next = t;
link x = t;
for (i = 2; i <= N; i++)
x = insert((x->next = new node(i, t)));
while (x != x->next)
{
for (i = 1; i < M; i++) x = x->next;
x->next = x->next->next;
}
cout << x->item << endl;
}
You could do it like this:
class Node
{
int item; Node* next;
public:
Node(int x, Node* t)
{
item = x; next = t;
}
int getItem() { return item; }
Node* getNext() { return next; }
void setNext(Node* n) { next = n; }
};
class List
{
Node *head = nullptr;
public:
void append(int n)
{
Node *tmp = new Node(n, head);
head = tmp;
}
Node* getHead() { return head; }
};
int main() {
int i, N = 9;
List list;
for (i = 1; i <= N; i++)
list.append(i);
Node* x = list.getHead();
// remove every second element
while (x != nullptr && x->getNext() != nullptr) {
Node* next = x->getNext();
x->setNext(next->getNext());
delete next;
x = x->getNext();
}
// print
x = list.getHead();
while (x != nullptr) {
std::cout << x->getItem() << std::endl;
x = x->getNext();
}
}
This way you have List in which you can insert. And Node which stores data.

Dot Product Calculation Link List Implementation

I am trying to implement the a dot product calculation formula into the linked list implementation on my below code and I am having the below error:
request for member 'add_node' in 'B', which is of pointer type 'linked_list {aka node*}' (maybe you meant to use '->' ?)
How can I clear that and make working code? I don't want to use classes as well
#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
typedef node* linked_list;
node *head = NULL;
node *tail = NULL;
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
int product=0;
while(A!=0 && B!=0)
{
if(A->index == B->index)
{
product = product + A->data * B->data;
A=A->next;
B=B->next;
}
else if(A->index < B->index)
{
A=A->next;
}
else
{
B=B->next;
}
}
return product;
return 0;
}
The error tells you what you need to know. linked_list is a pointer. You need to use the -> operator, not the dot operator.
Additionally, your node struct does not contain a method called add_node(). In fact it doesn't contain any methods at all.
#include <iostream>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
};
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
display(A.gethead());
display(B.gethead());
int product=0;
node *current_a = A.gethead();
node *current_b = B.gethead();
while(current_a != 0 && current_b!=0)
{
if(current_a->index == current_b->index)
{
product = product + current_a->data * current_b->data;
current_a=current_a->next;
current_b=current_b->next;
}
else if(current_a->index < current_b->index)
{
current_a=current_a->next;
}
else
{
current_b=current_b->next;
}
}
cout<<"\nDot Product : "<< product<<endl;
return 0;
}
enter code here

Singly-Linked List Add Function - Read Access Violation

I'm trying to create a basic singly-linked list using a separate Node class and LinkedList class. I barely know what I'm doing as I've just started learning C++, so any help would be greatly appreciated.
The LinkedList part of the code runs on its own, but I'm sure there are some corrections to be made there too. My main problem is that, when trying to add to the linked list, I'm getting (at line 64 of LinkedList.h):
Exception thrown: read access violation. this->head was nullptr.
I'm using Microsoft Visual Studio 2015. Here's the code:
LinkedList.h (it's inline):
#pragma once
#include <iostream>
using namespace std;
class Node
{
private:
Node *next = NULL;
int data;
public:
Node(int newData) {
data = newData;
next = NULL;
}
Node() {
}
~Node() {
if(next)
delete(next);
}
Node(int newData, Node newNext) {
data = newData;
*next = newNext;
}
void setNext(Node newNext) {
*next = newNext;
}
Node getNext() {
return *next;
}
int getData() {
return data;
}
};
class LinkedList
{
private:
Node *head;
int size;
public:
LinkedList()
{
head = NULL;
size = 0;
}
~LinkedList()
{
}
void add(int numberToAdd)
{
head = new Node(numberToAdd, *head);
++size;
}
int remove()
{
if (size == 0) {
return 0;
}
else {
*head = (*head).getNext();
--size;
return 1;
}
}
int remove(int numberToRemove)
{
if (size == 0)
return 0;
Node *currentNode = head;
for (int i = 0; i < size; i++) {
if ((*currentNode).getData() == numberToRemove) {
*currentNode = (*currentNode).getNext();
return 1;
}
}
}
void print()
{
if (size == 0) {
return;
}
else {
Node currentNode = *head;
for (int i = 0; i < size; i++) {
cout << currentNode.getData();
currentNode = currentNode.getNext();
}
cout << endl;
}
}
};
List Tester.cpp
// List Tester.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "LinkedList.h"
using namespace std;
int main()
{
LinkedList myList;
myList.add(4);
system("pause");
}
You are making copies where you should not:
This:
Node(int newData, Node newNext) {
data = newData;
*next = newNext;
}
should be:
Node(int newData, Node* newNext) {
data = newData;
next = newNext;
}
Because now this:
head = new Node(numberToAdd, *head);
becomes this:
head = new Node(numberToAdd, head);
and will work even if head is a null pointer. You may need to adjust your other code accordingly.
Your whole implementation is full of errors. It should look more like this instead:
#pragma once
#include <iostream>
class Node
{
private:
int data;
Node *next;
public:
Node(int newData, Node *newNext = NULL)
: data(newData), next(newNext)
{}
void setNext(Node *newNext) {
next = newNext;
}
Node* getNext() {
return next;
}
int getData() {
return data;
}
};
class LinkedList
{
private:
Node *head;
int size;
public:
LinkedList()
: head(NULL), size(0)
{
}
~LinkedList()
{
Node *currentNode = head;
while (currentNode)
{
Node *nextNode = currentNode->getNext();
delete currentNode;
currentNode = nextNode;
}
}
void add(int numberToAdd)
{
head = new Node(numberToAdd, head);
++size;
}
bool remove()
{
Node *currentNode = head;
if (!currentNode)
return false;
head = currentNode->getNext();
delete currentNode;
--size;
return true;
}
bool remove(int numberToRemove)
{
Node *currentNode = head;
Node *previousNode = NULL;
while (currentNode)
{
if (currentNode->getData() == numberToRemove)
{
if (head == currentNode)
head = currentNode->getNext();
if (previousNode)
previousNode->setNext(currentNode->getNext());
delete currentNode;
return true;
}
previousNode = currentNode;
currentNode = currentNode->getNext();
}
return false;
}
void print()
{
Node *currentNode = head;
if (!currentNode) return;
do
{
std::cout << currentNode->getData();
currentNode = currentNode->getNext();
}
while (currentNode);
std::cout << std::endl;
}
};
Which can then be simplified using the std::forward_list class (if you are using C++11 or later):
#pragma once
#include <iostream>
#include <forward_list>
#include <algorithm>
class LinkedList
{
private:
std::forward_list<int> list;
public:
void add(int numberToAdd)
{
list.push_front(numberToAdd);
}
bool remove()
{
if (!list.empty())
{
list.pop_front();
return true;
}
return false;
}
bool remove(int numberToRemove)
{
std::forward_list<int>::iterator iter = list.begin();
std::forward_list<int>::iterator previous = list.before_begin();
while (iter != list.end())
{
if (*iter == numberToRemove)
{
list.erase_after(previous);
return true;
}
++previous;
++iter;
}
return false;
}
void print()
{
if (list.empty()) return;
std::for_each(list.cbegin(), list.cend(), [](int data){ std::cout << data });
std::cout << std::endl;
}
};