I have the following code. The problem is that if I choose an option, for example option #2 to sort the elements the program it's closing and I don't understand why... I'm using Eclipse IDE. The functions do the following:
a) A function to insert a data in a list that does not allow duplicate values (if the value does
not exist, pasting takes place at the beginning of the list). Payload elements to be integer.
b) A function to insert a data in a list so the list remains sorted ascending. Payload elements
to be integer
c) A function to determine the number of elements divisible by a z value received as
parameter.
d) A function to determine the number of elements greater than the information from the
first node of the list.
e) A function that determines the number of occurrences of a given value in the list.
#include<iostream>
using namespace std;
char menu()
{ char choice;
cout<<"********Choose an option********* \n" ;
cout<<"1. duplicate check\n";
cout<<"2. Sort the elements \n";
cout<<"3. Determine elements divisible by a value given Z \n";
cout<<"4. Determine the number of elements greater than the first node\n";
cout<<"5. Determine the number of occurrences in a list\n";
cout<<"6. -----Exit-----\n";
cin>>choice;
return choice;
}
struct node
{
int value;
node* prev;
node* next;
};
typedef node* pnode;
int nro=0;
void showlist(pnode start, int div)
{
nro=0;
if(start!=NULL)
{
while(start!=NULL)
{
if(start->value%div==0)
{
nro++;
cout<<start->value<<" ";
}
start=start->next;
}
}
}
void checkvalue(pnode start, int nr)
{
nro=0;
if(start!=NULL)
{
while(start!=NULL)
{
if(start->value==nr)
{
nro++;
}
start=start->next;
}
}
}
bool checkduplicates(pnode start, int val)
{
if(start==NULL) return false;
else
{
while(start!=NULL)
{
if(start->value==val) return true;
start=start->next;
return false;
}
}
}
void sort(pnode start)
{
pnode p=start;
pnode q=NULL;
while(p->next!=NULL)
{
q=p->next;
while(q!=NULL)
{
if(p->value > q->value)
{
int aux;
aux=p->value;
p->value=q->value;
q->value=aux;
}
q=q->next;
}
p=p->next;
}
}
void showbig(pnode start)
{
pnode q=start->next;
while(q!=NULL)
{
if(q->value > start->value)
{
cout<<q->value<<" ";
}
q=q->next;
}
}
int main()
{
pnode start=NULL;
pnode end=NULL;
pnode aux=NULL;
char choice;
int number;
do{
choice=menu();
switch(choice)
{
case '1':
int z;
cout<<"Value: ";
cin>>z;
if(start==NULL)
{
start = new node;
start->value=z;
start->next=NULL;
start->prev=NULL;
end=start;
aux=start;
}
else
{
aux= new node;
aux->value=z;
aux->next=start;
start->prev=aux;
aux->prev=NULL;
start=aux;
}
if (!checkduplicates(start,z))
{cout<<"Duplicate value. Cannot insert.\n";
break;}
break;
case '2':
sort(start);
break;
case '3':
cout<<"Value: ";
cin>>z;
showlist(start,z);
if(nro==0) cout<<"No values found.\n";
else cout<<"\n";
break;
case '4':
showbig(start);
cout<<"\n";
break;
case '5':
cout<<"Value: ";
cin>>z;
checkvalue(start,z);
if(nro==0) cout<<"No values found.\n";
else cout<<nro<<"\n";
break;
default: cout<<"Exit \n";
}
} while (choice !='6');
return 0;
}
sort(start);
is failing because start is NULL which means p is NULL
pnode p = start;
And you try to dereference a NULL pointer here
while (p->next != NULL)
Related
#include<iostream>
using namespace std;
//initiating a class 'node' that is used to store the data and address of an element
class Node
{
public:
//initialising the data members
int information;
//self referential data members
Node *leftSection;
Node *rightSection;
//default constructor
//initialises the data members when a node is created.
Node()
{
information = 0;
leftSection = NULL;
rightSection = NULL;
}
};
//class that implements Binary Search Tree
class BinarySearchTree
{
public:
//method to insert elements into a binary tree
void insertIntoBinaryTree( int number, Node *root )
{
//checking if tree is empty
if(root == NULL)
{
Node *root = new Node;
root->information = number;
root->leftSection = NULL;
root->rightSection = NULL;
cout<<"Success";
}
else
{
//checking the left section condition
if(number < root->information)
{
insertIntoBinaryTree( number, root->leftSection );
cout<<"Success";
}
else if(number > root->information)
{
insertIntoBinaryTree( number, root->rightSection );
cout<<"Success";
}
else
{
cout<<"\nElement Already Exists !";
}
}
}
void displayBinaryTreeInOrder( Node *root )
{
if(root == NULL)
{
cout<<"\nNo Elements in the Tree ";
return;
}
displayBinaryTreeInOrder(root->leftSection);
cout<<root->information<<" - ";
displayBinaryTreeInOrder(root->rightSection);
}
};
class callAllMethods
{
public:
char menu()
{
char choice;
cout<<endl;
cout<<"\n---MENU---";
cout<<"\n1.Add an Item into Binary Search Tree";
cout<<"\n2.Remove an Item from Binary Search Tree";
cout<<"\n3.Remove an Item (2).";
cout<<"\n4.Remove an Item (3)";
cout<<"\n5.Traverse the Binary Search Tree - In Order";
cout<<"\n\nEnter your Option: ";
cin>>choice;
return choice;
}
void Call()
{
int value;
BinarySearchTree user;
Node *Key = NULL;
char choice;
int number;
int numberToBeChecked;
do{
choice = menu();
switch(choice)
{
case '1': cout<<"\nEnter the Number To Be Inserted into the Tree ";
cin>>value;
user.insertIntoBinaryTree(value,Key);
break;
case '2':user.displayBinaryTreeInOrder(Key);
break;
case '3':
break;
case '4':
break;
case '5': user.displayBinaryTreeInOrder(Key);
break;
default : cout<<"System Exit";
}
}while(choice!='6');
}
};
int main()
{
callAllMethods Object;
Object.Call();
}
My program splits the original linked list into halves after I call function binary search function, any way i can keep the original single linked list and calling the function? i did try to create a 2 extra nodes start2 and start1, and tried to copy all of the data of original start into start2 but again it just splits the original linked list.
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
//declaring
struct node{
int info;
struct node* next;
};
node* start= NULL;
node* start1= NULL;
node* start2= NULL;
int count = 0;
void createlist(int value){
node *q,*tmp;
tmp=new(struct node);
tmp->info=value;
tmp->next=NULL;
if(start==NULL) start=tmp; /*if list is empty*/
else /*element inserted at end*/
{
q=start;
while(q->next!=NULL) q=q->next;
q->next=tmp;
}}
int getCount(node* head)
{
// Initialize count
// Initialize current
node* current = head;
while (current != NULL)
{
count++;
current = current->next;
}
return count;
}
int Split( node *start2, node **start1)
{
struct node *slow, *fast;
if(start2->next==NULL) /*only one element*/
return 0;
slow=fast=start2;
while(fast->next!=NULL && fast->next->next!=NULL)
{
slow = slow->next;
fast = fast->next->next;
}
*start1 = slow->next;
slow->next = NULL;
}//End of Split()//
int binarysearch(int number){
start2= start;
getCount(start2);
int midindex;
midindex = count/2;
node* temp;
temp = start2;
int middle= 1;
while(middle != midindex){
temp = temp->next;
middle++;
}
Split(start2, &start1);
if (temp->info == number){
cout<<"The number is at "<<middle <<"index"<<endl;
}
middle++;
if (temp->info<number){
node* temp1 = start1;
while(temp1->info != number){
temp1= temp1->next;
middle++;}
cout<<"The number exist at the "<< middle <<endl;
}
if (temp->info>number){
node* temp2 = start2;
int newcount =1;
while(temp2->info != number){
temp2= temp2->next;
newcount++;
}
cout<<"The number exist at the "<< newcount <<endl;
}
}
void display()
{
struct node *q;
if(start==NULL)
{
cout<<"List is empty"<<endl;
return;
}
q=start;
cout<<"List is:"<<endl;
while(q!=NULL)
{
cout<<q->info<<" ";
q=q->next;
}
cout<<endl;
}
int main(){
int ch, val;
cout<<"1) Push in stack"<<endl;
cout<<"2) Search the number "<<endl;
cout<<"3) Display "<<endl;
cout<<"4) Exit"<<endl;
do {
cout<<"Enter choice: "<<endl;
cin>>ch;
switch(ch) {
case 1: {
cout<<"Enter value to be pushed:"<<endl;
cin>>val;
createlist(val);
break;
}
case 2: {
int n;
cout<<"Enter the value you want to be searched"<<endl;
cin>>n;
binarysearch(n);
break;
}
case 3: {
display();
break;
}
case 4: {
cout<<"Exit"<<endl;
break;
}
default: {
cout<<"Invalid Choice"<<endl;
}
}
}while(ch!=4);
return 0;
}
I have a non stl tree. I'm having problems with the function void preorder. It's supposed to print out all elements that have 2 'children' and to print out the total number of parents with 2 children. I can't make it to print out the number parents. Everything else works good so far. Do you know how to make it better?
#include <iostream>
using namespace std;
struct elem
{
int key;
elem *left;
elem *right;
}*root=NULL;
void add(int n, elem *&t);
int del(int k);
elem * &search(int k);
void show(elem *t, int h);
void printnode(int n, int h);
void preorder(elem *t);
int main()
{
int ch, num, amount, i;
do
{ cout<<"\n\t \t Menu";
cout<<"\n \t 1.Add elements";
cout<<"\n \t 2.Search an element";
cout<<"\n \t 3.Print the tree";
cout<<"\n \t 4.Delete an element";
cout<<"\n \t 5. Find elements with two children";
cout<<"\n \t 6.Exit";
do
{ cout<<"\n \t Your choice is:\t";
cin>>ch;
}
while (ch<1||ch>6);
switch(ch)
{
case 1:
cout<<"\n \t How many elements do you want to add?\t";
cin>>amount;
for(i = 0; i < amount; i++)
{
cout<<"\n\t Input list elements:\t";
cin>>num;
add(num, root);
}
break;
case 2:
int b;
cout<<"\n \tWhat element do you want to find?";
cin>>b;
&search(b);
break;
case 3:
cout<<"\n \n \n";
show(root, 0);
break;
case 4:
cout<<"\n \t Which element do you want to delete?";
int a;
cin>>a;
&search(a);
break;
case 5:
preorder(root);
break;
}
}while(ch!=6);
}
void add(int n, elem *&t)
{
if (t==NULL) {
t=new elem;
t->key=n;
t->left=t->right=NULL;
} else
{
if (t->key<n)
add(n,t->right);
else
{
if (t->key>n)
add(n,t->left);
}
}
}
elem * &search(int k)
{
elem **p=&root;
for (;;)
{
if (*p==NULL)
return *p;
if (k<(*p)->key)
p=&(*p)->left;
else
if (k>(*p)->key) p=&(*p)->right;
else
return *p;
}
}
int del(int k)
{
elem * &p=search(k), *p0=p, **qq, *q;
if (p==NULL)
return 0;
if ((p->right==NULL))
{
p=p->left; delete p0;
}
else
if(p->left==NULL)
{
p=p->right; delete p0;
}
else
{
qq=&p->left;
while ((*qq)->right)
qq=&(*qq)->right;
p->key=(*qq)->key;
q=*qq;
*qq=q->left;
delete q;
}
return 1;
}
void printnode(int n, int h)
{
for(int i=0;i<h;i++)
cout<<"\t";
cout<<n<<endl;
}
void show(elem *t, int h)
{
if(t)
{
show(t->right,h+1);
printnode(t->key,h);
show(t->left,h+1);
}
}
void preorder(elem *t)
{
int count_total=0;
if (t)
{
int count=0;
if (t->left!=NULL&&t->right!=NULL)
{
int child_key=0;
count++;
cout<<"\n \t Element is:\n\t"<<t->key;
if(count>count_total)
{
count_total=count;
}
}
preorder(t->left);
preorder(t->right);
}
cout<<"\n\tTotal number of elements:"<<count_total;
}
We can have the function return the total number of nodes (having 2 children) occurring in the sub-tree emanating from the node root. Suppose left_count and right_count is the number of such nodes occurring in the left and right sub-tree of root respectively, then we return left_count + right_count if root doesn't have 2 children but if it does, then we return left_count + right_count + 1.
int preorder(elem *root)
{
if (root == nullptr)
return 0;
int left_count, right_count;
left_count = preorder(root->left);
right_count = preorder(root->right);
bool is_valid = false;
if (root->left != nullptr && root->right != nullptr)
{
cout << root->key << endl;
is_valid = true;
}
return left_count + right_count + (is_valid ? 1 : 0);
}
I have made a program in c++ to delete a node in a singly linked list but it is not working as predicted. I am attaching pictures of the output for better clarity that whats misbehaving.
code:
int del_node(int val_del) //this section is producing error
{
node* temp_del=head;
if(head==nullptr)
{
cout<<"no element to delete.!";
exit(0);
}
else
{
while(temp_del->next!=nullptr)
{
if(temp_del->next->data==val_del)
{
temp_del->next=temp_del->next->next;
delete temp_del->next->next;
}
temp_del=temp_del->next;
}
}
return 0;
}
This a function of a class.
Here is the complete code if it helps:
#include<iostream>
using namespace std;
struct node
{
int data;
node *next;
};
class linked_list
{
node *head,*tail;
public:
linked_list()
{
head=nullptr;
tail=nullptr;
}
int create_last(int val_last)
{
node *temp=new node; if(!temp){cout<<"memory not allocated"; exit(1);}
temp->data=val_last;
temp->next=nullptr;
if(head==nullptr)
{
head=temp;
tail=temp;
}
else
{
tail->next=temp;
tail=temp;
}
return 0;
}
int create_beg(int val_beg)
{
node *temp_head=nullptr;
node *temp=new node; if(!temp){cout<<"memory not allocated"; exit(1);}
temp->data=val_beg;
temp->next=nullptr;
if(head==nullptr)
{
head=temp;
tail=temp;
}
else
{
temp_head=head;
head=temp;
temp->next=temp_head;
}
return 0;
}
int del_node(int val_del) //this section is producing error
{
node* temp_del=head;
if(head==nullptr)
{
cout<<"no element to delete.!";
exit(0);
}
else
{
while(temp_del->next!=nullptr)
{
if(temp_del->next->data==val_del)
{
temp_del->next=temp_del->next->next;
delete temp_del->next->next;
}
temp_del=temp_del->next;
}
}
return 0;
}
int show()
{
node* temp_show=head;
while(temp_show!=nullptr)
{
cout<<temp_show->data<<"\n";
temp_show=temp_show->next;
}
return 0;
}
}info;
int main()
{
int choice,ele; char cont;
rep:
cout<<"1. Insert node at the end\n";
cout<<"2. Insert node at beg\n";
cout<<"3. Delete node\n";
cout<<"4. Show nodes\n";
cout<<"5. Exit\n";
cout<<"enter your choice: ";
cin>>choice;
switch(choice)
{
case 1: cout<<"Enter element: ";
cin>>ele;
info.create_last(ele);
break;
case 2: cout<<"Enter element: ";
cin>>ele;
info.create_beg(ele);
break;
case 3: cout<<"Enter element: ";
cin>>ele;
info.del_node(ele);
break;
case 4: info.show();
break;
case 5: exit(0);
break;
default: cout<<"Wrong choice, Bye.!!";
exit(0);
}
cout<<"Do you want to continue(y/n): ";
cin>>cont;
if(cont=='y'||cont=='Y')
{
goto rep;
}
else
{
cout<<"thank you";
exit(0);
}
return 0;
}
int del_node(int val_del) {
node* temp_del = head;
if(head == nullptr) {
cout<<"no element to delete.!";
exit(0);
} else if(head->data == val_del) {
// If head is to be deleted
head = head->next;
} else {
while(temp_del->next != nullptr) {
if(temp_del->next->data == val_del) {
temp_del->next=temp_del->next->next;
// delete temp_del->next->next; This is wrong deletion
}
temp_del = temp_del->next;
}
}
// delete the node if one found else not
if (temp_del != nullptr)
delete temp_del;
return 0; // This should return true or false, do check what you want as return type
}
The del_node function has two problems:
1) It can't delete the node when the list has exactly 1 element
2) It deletes the wrong element
So let's start with number 1 and look at the code:
if(head==nullptr)
{
cout<<"no element to delete.!";
exit(0);
}
else
{
while(temp_del->next!=nullptr)
Assume that the list contains exactly one element. That means:
a) head is not NULL
b) head->next and therefore also temp_del->next is NULL
so while(temp_del->next!=nullptr) will result in false, i.e. the loop will no be executed. The overall result is that the code does nothing.
Now for number 2. The code is:
if(temp_del->next->data==val_del)
{
temp_del->next=temp_del->next->next; // You want to delete temp_del->next
// but here you change it
delete temp_del->next->next; // so here you delete the wrong node
// there is also an extra ->next
}
You need a temp variable to hold a pointer to the node you want to delete.
You probably want the code to be:
int del_node(int val_del)
{
// Delete elements in the front
while (head!=nullptr && head->data==val_del)
{
node* node_to_delete = head;
head = head->next;
delete node_to_delete;
// return 0; Uncomment if you only want one delete per function call
}
if(head==nullptr) return 0;
// Delete elements not in the front
node* temp_del=head;
while(temp_del->next!=nullptr)
{
if (temp_del->next->data==val_del)
{
node* node_to_delete = temp_del->next;
temp_del->next = temp_del->next->next;
delete node_to_delete;
// return 0; Uncomment if you only want one delete per function call
}
temp_del=temp_del->next;
}
return 0;
}
I have a C++ Code that just manipulates basic linked list - add a new node, delete a node and view the list
//UNIX Environment
#include <iostream>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#define clear() printf("\033[H\033[J")
using namespace std;
struct node
{
int val;
node *next;
};
struct node* head = NULL;
void add_node(struct node *hea)
{
char f;
int val;
cout<<"Enter value : ";
cin>>val;
if(head==NULL)
{
head = new(struct node);
head->val = val;
head->next = NULL;
}
else
{
node *traverser = hea;
node *traverser_prev = NULL;
while(traverser!=NULL)
{
traverser_prev = traverser;
traverser=traverser->next;
}
traverser = new(struct node);
traverser->val = val;
traverser->next = NULL;
traverser_prev->next=traverser;
}
cout<<"\nEnter Y to return : ";
cin>>f;
while(f!='Y')
{
cout<<"Wrong entry.Enter again : ";
cin>>f;
}
return;
}
void view_list(struct node *hea)
{
char f;
node *traverser = hea;
while(traverser!=NULL)
{
cout<<traverser->val<<" ";
traverser=traverser->next;
}
cout<<"\nEnter Y to return : ";
cin>>f;
while(f!='Y')
{
cout<<"Wrong entry.Enter again : ";
cin>>f;
}
return;
}
void delete_node(node *hea)
{
char f;
int del_value;
cout<<"Enter value to be deleted :";
cin>>del_value;
node *traverser = hea;
cout<<"OK1\n";
node* traverser_prev = NULL;
cout<<"OK2\n";
while(traverser!=NULL)
{
if(traverser->val==del_value)
{
if(traverser==hea)
{
hea=traverser->next;
cout<<"Here cond1\n";
delete traverser;
}
else
{
traverser_prev->next = traverser->next;
cout<<"Here cond2\n";
}
}
else
{
traverser_prev = traverser;
traverser = traverser->next;
cout<<"Here cond3\n";
}
}
cout<<"\nEnter Y to return : ";
cin>>f;
while(f!='Y')
{
cout<<"Wrong entry.Enter again : ";
cin>>f;
}
return;
}
int main(int argc, char* argv[])
{
while(1)
{
clear();
int choice;
cout<<"POINTER BASICS\n";
cout<<"1. Add new element\n";
cout<<"2. View elements\n";
cout<<"3. Delete element\n";
cout<<"4. Exit\n";
cout<<"Enter choice: ";
cin>>choice;
switch(choice)
{
case 1: add_node(head);
break;
case 2: view_list(head);
break;
case 3: delete_node(head);
break;
default:break;
}
if(choice==4)
break;
}
}
However, whenever I try to delete node, it throws me a segmentation fault error with core dumped. What is the reason for the error?
One problem is that in the delete_node function you pass the list head by value, which means that the pointer is copied and inside the function you only modify the copy.
There are two solutions: Either don't use the argument at all and only use the global variable, or pass the argument by reference:
void delete_node(node*& hea)
Is it possible that when you are executing the line
traverser_prev->next = traverser->next;
traverser_prev == NULL?