Linked List Program error in C++ - c++

I tried implementing Linked List using C++ using a structure.
I've included three functions - Size, Insertion and Deletion from the end.
The program compiled successfully. During execution, when I tried to give input for the LLInsert() function, there was just a cursor blinking on my execution window. I don't know if the function returned to main.
Also the LLSize() doesn't return 0 when I try to find the Size of a empty list.
I can't seem to figure out what I'm doing wrong. Here is my code.
#include<iostream>
using namespace std;
struct LL {
LL *next = NULL;
int data;
};
int LLSize(LL *head) {
LL *current = new LL;
current = head;
int count = 0;
while(current != NULL) {
current = current -> next;
count ++;
}
return count;
}
void LLInsert(LL *head,int value) {
LL *current = new LL;
current = head;
LL *Newnode = new LL;
Newnode -> data = value;
Newnode -> next = NULL;
if(head == NULL) {
head = Newnode;
return;
}
while(current->next != NULL) {
current = current->next;
}
current->next = Newnode;
return;
}
int LLDelete(LL *head) {
LL *current = new LL;
current = head;
int deleteddata;
while(current->next->next != NULL) {
current = current->next;
}
current->next->data = deleteddata;
current->next = NULL;
return deleteddata;
}
int main() {
int choice;
LL *A;
while(1) {
cout << "1. Size\n2. Insert\n3. Delete\n4. Exit" << endl;
cout << "Enter a choice : ";
cin >> choice;
switch(choice) {
case 1 : {
cout << "\nLength = " << LLSize(A) << endl;
break;
}
case 2 : {
int value;
cout << "\nEnter the element to insert : ";
cin >> value;
LLInsert(A,value);
break;
}
case 3 : {
cout << LLDelete(A);
break;
}
case 4 : {
exit(0);
}
default : {
cout << "\nInvalid choice. Enter a valid choice " << endl;
break;
}
}
}
}

Don't use using namespace.
Create a type for the list and a type for the nodes
struct LL {
LL* next;
int data;
};
struct L {
LL* head;
};
Use references and don't allocate new memory in each function
int LLSize(L& list) {
LL *current = list.head;
Check if the head of the list is set and use nullptr
if (list.head == nullptr) {
Use an instance of the list and not a pointer
int main() {
int choice;
L A;
Use a debugger like gdb to analyze your program.
Clean up at the end. Delete memory you allocated with new. One delete for each new.

Related

Only Printing the First Value of Linked List

I have no idea why display function is not displaying anything other than the first node's data. I've tried switching the While(p!=NULL) to while(p->next!= NULL but when I do that instead of only the first node's data displaying no data is being displayed.
#include <iostream>
using namespace std;
class Node {
public:
int no;
Node* next;
};
Node* createNode(int no1) {
Node* n = new Node();
n->no = no1;
n->next = NULL;
return n;
}
void addValue(int x, Node** head) {
//insert first node into linked list
Node* n = createNode(x),*p = *head;
if (*head == NULL) {
*head = n;
}
//insert second node onwards into linked list
else {
while (p->next!= NULL) {
p->next = n;
p = p->next;
}
}
}
void display(Node *head) {
Node* temp = head;
// temp is equal to head
while (temp->next!=NULL) {
cout << temp->no;
temp = temp->next;
}
}
int main() {
int num; char choice;
Node* head = NULL;
do {
cout << "Enter a number : ";
cin >> num;
addValue(num,&head);
cout << "Enter [Y] to add another number : ";
cin >> choice;
} while (choice == 'Y');
cout << "List of existing record : ";
display(head);
return 0;
}
I've tried changing the contents fo the else while loop in the addRecord function to p = p->next; p->next = n; in that order to no avail.
In the while loop, it should be
while (p->next!= NULL) {
p = p->next;
}
p->next = n;
Traverse until the end of linked list is reached and then, add the new entry.

How i can create a single list , then create two single lists from it one of them for even numbers and another for odd numbers?

I'm a beginner programmer in my first years in college, I'm working with single linked lists in c++, and I'm trying to write a program without using classes
to create a single linked list input from a user and print it, then I want to put the even numbers
in a new list and print this new list and the odd numbers in another new list and
print it too.
I began with this, I wish if someone can help me.
#include <iostream>
using namespace std;
struct node {
int data;
node* next;
};
struct Even_node {
int even_data;
Even_node* even_next;
};
void creat(node*& head, node*& tail)
{
int num;
cout << "enter number , (0) to quiet\n";
cin >> num;
while (num != 0) {
node* nptr = new node;
nptr->data = num;
if (head == nullptr)
head = nptr;
else
tail->next = nptr;
tail = nptr;
tail->next = nullptr;
cout << "enter number again or 0 to quiet\n";
cin >> num;
}
}
void print(node* head)
{
cout << "the list is:\t";
while (head != nullptr) {
cout << head->data << "\t";
head = head->next;
}
cout << endl;
}
main()
{
node *head = nullptr, *tail = nullptr;
creat(head, tail);
print(head);
}
First I fixed the problems
removed dynamic memory allocations and memory leaks
it's int main https://en.cppreference.com/w/cpp/language/main_function
#include <iostream>
#include <memory>
using std::cout;
using std::cin;
struct node {
int data;
std::unique_ptr<node> next;
};
struct list {
std::unique_ptr<node> head;
node *tail;
};
void creat(list &l)
{
int num;
cout << "enter number , (0) to quiet\n";
cin >> num;
while (num != 0) {
std::unique_ptr<node> nptr = std::make_unique<node>();
nptr->data = num;
if (!l.head) {
l.head = std::move(nptr);
l.tail = l.head.get();
} else {
l.tail->next = std::move(nptr);
l.tail = l.tail->next.get();
}
cout << "enter number again or 0 to quiet\n";
cin >> num;
}
}
void print(const list &l)
{
auto node = l.head.get();
cout << "the list is:\t";
while (node != nullptr) {
cout << node->data << "\t";
node = node->next.get();
}
cout << '\n';
}
int main()
{
list l;
creat(l);
print(l);
}
Now you can create a second list, call it even, iterate through the first list and copy all even elements into the second list.

How to remove a certain node from a linked list by the data its holding?

We are suppose to enter a string, and then find where the string is in the linked list and remove that node
when i insert to the front of the list, so i enter data values a, b, c , d, when i print it it comes up as d,c,b,a. Now i insert to the rear of it, entering f and g, and the list now looks, d,c,b,a,f,g. I want to remove f but it just use the remove function it does not and still output the same list
using namespace std;
struct node {
string data;
node* next;
};
node* addFront(node* s);
node* addRear(node* s);
void remove(node* head, string abc);
void print(node* head);
int main() {
node* head = NULL;
cout << "Enter 5 data strings\n";
cout << "This will be inserted from the back\n";
for (int i = 0; i < 5; i++) {
head = addFront(head);
}
print(head);
cout << "Enter 3 strings and this will be inserted from the back of the orignal string\n";
for (int i = 0; i < 3; i++) {
head = addRear(head);
}
print(head);
cout << "Removing the head node\n";
string n;
cout << "Enter a string to remove\n";
cin >> n;
remove(head, n);
print(head);
}
node* addFront(node* s)
{
node* person = new node;
cin >> person->data;
person->next = s;
s = person;
return s;
}
node *addRear(node*s ) {
node* person = new node;
cin >> person->data;
person->next = NULL;
if (s == NULL) {
return person;
}
else {
node* last = s;
while (last->next != NULL) {
last = last->next;
}
last->next = person;
}
return s;
}
void remove(node* head, string a) {
node* previous = NULL;
node* current = head;
if (current == NULL) {
cout << "Value cannot be found\n";
return;
}
else {
while (previous != NULL) {
if (current->data == a) {
previous->next = current->next;
delete current;
break;
}
current = current->next;
}
}
}
void print(node * head)
{
node* temp = head;
while (temp != NULL) // don't access ->next
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
In remove function, previous is most certainly NULL when you hit that while loop.
Perhaps consider a do-while loop instead (with better handling of previous).
You may be better off handling the first node in a different manner since the holder of its previous is essentially the root pointer.

linked list insert and printing C++

So i am trying to use double pointers to create insert function and then print the linked list.
I managed to do it with single pointers but this double pointer is driving me insane.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
string name;
int ID;
int marks[10];
Node *next;
};
void printOptions() {
cout << endl;
cout << "1.Insert New Node" << endl;
cout << "2.Print List" << endl;
cout << "3.Exit" << endl;
}
void insertAtBack(string inputName, Node **headref) {
Node **currentNodeRef;
currentNodeRef = headref;
while ((*currentNodeRef)->next != NULL) {
(*currentNodeRef) = (*currentNodeRef)->next;
}
(*currentNodeRef)->next = new Node();
(*currentNodeRef)->next->name = inputName;
(*currentNodeRef)->next->next = NULL;
}
void printList(Node *head) {
Node *indexNode;
indexNode = head;
while (indexNode != NULL) {
cout << (indexNode)->name << endl;
(indexNode) = (indexNode)->next;
}
}
int main() {
cout << "This implements a linked list" << endl;
int option;
bool infinite = true;
Node *head = NULL;
string testName;
while (infinite == true) {
printOptions();
std::cin >> option;
switch (option) {
case 1:
cout << "Enter student name" << endl;
std::cin >> testName;
if (head == NULL) {
head = new Node();
head->name = testName;
}
else {
insertAtBack(testName, &head);
}
break;
case 2:
printList(head);
break;
case 3:
exit(1);
break;
default:
exit(1);
break;
}
}
return 0;
}
So there is no compilation error or seg fault but instead the code runs it takes in 2 values and prints them fine. when the another value is typed inserted it only prints 2 values no more.
I think the print function is good because it worked previously with single pointer but i am not 100% sure.
I think the problem is in the insert function but i am not sire where.
void insertAtBack(string inputName, Node **headref) {
Node **currentNodeRef;
currentNodeRef = headref;
...
Node **currentNodeRef = headref; is an error. Remember you are passing the address of a pointer. You mean to write:
Node *currentNodeRef = *headref;
And change the function like so:
void insertAtBack(string inputName, Node **head)
{
Node *tail = *head;
while(tail->next != NULL)
tail = tail->next;
tail->next = new Node();
tail->next->name = inputName;
tail->next->next = NULL;
}
Also don't forget to initialize head->next = nullptr;
if (head == NULL) {
head = new Node();
head->name = testName;
head->next = nullptr; <--- add
}
It is better however if insertAtBack is prepared to handle head when head is NULL. The whole reason you pass Node **head is because you want a reference to the pointer so you can initialize it. So you can modify the code as:
void insertAtBack(string inputName, Node **head)
{
Node *new_node = new Node();
new_node->name = inputName;
new_node->next = nullptr;
if(*head)
{
Node *tail = *head;
while(tail->next)
tail = tail->next;
tail->next = new_node;
}
else
{
*head = new_node;
}
}
void printList(Node *head)
{
Node *node = head;
while(node)
{
cout << node->name << endl;
node = node->next;
}
}
int main()
{
cout << "This implements a linked list" << endl;
Node *head = NULL;
string testName;
while(true)
{
printOptions();
int option;
std::cin >> option;
switch(option)
{
case 1:
cout << "Enter student name" << endl;
std::cin >> testName;
insertAtBack(testName, &head);
break;
case 2: printList(head); break;
case 3: exit(1); break;
default: exit(1); break;
}
}
return 0;
}

Output of c++ program not coming as expected

I have made a C++ program for a binary tree. But the terminal is not asking the statement for inputting the direction for where the elements are to be placed.
Also when I replace the statement from " node *temp = new node " to "node *temp=NULL" the program stops working .
#include <iostream>
#include <cstring>
using namespace std;
class node {
int data;
node * left;
node * right;
public:
node * level_order(node * first);
node * create_bt(node * first);
void display(node * first);
};
//node *first=NULL;
node * node::create_bt(node * first) {
node * temp = new node;
int ele;
//char dir;
cout << "\n Enter data ";
cin >> ele;
temp->data = ele;
temp->left = NULL;
temp->right = NULL;
if (first == NULL) {
temp = first;
return first;
} else {
char dir[20];
cout << "\n Enter the direction ";
cin >> dir;
node * cur = first;
int j = 0;
while (dir[j] != '\0') {
if (dir[j] == 'l') {
cur = cur->left;
}
if (dir[j] == 'r') {
cur = cur->right;
}
j++;
}
cur = temp;
return first;
}
}
void node::display(node * first) {
if (first == NULL)
return;
cout << "\n " << first->data;
display(first->left);
display(first->right);
}
int main() {
int n;
node s;
node * first = NULL;
cout << "\n No of elements ";
cin >> n;
for (int i = 0; i < n; i++) {
first = s.create_bt(first);
}
s.display(first);
return 0;
}
first=s.create_bt(first); does not changes state, from NULL to 'l' or 'r'. You have to change that.
node*node::create_bt(node *first)
{
node *temp=new node;
int ele;
//char dir;
cout<<"\n Enter data ";
cin>>ele;
temp->data=ele;
temp->left=NULL;
temp->right=NULL;
char dir[20];
cout<<"\n Enter the direction ";
cin>>dir;
if(first==NULL)
{
temp=first;
return first;
}
else
{
node*cur=first;
int j=0;
while(dir[j]!='\0')
{
if(dir[j]=='l')
{
cur=cur->left;
}
if(dir[j]=='r')
{
cur=cur->right;
}
j++;
}
cur=temp;
return first;
}
}
I believe you re looking something like this. This is a basic binary tree, i had to make a basic one in order to understand how it works and how it chooses left and right. I make a class inside a class, in order to have access to my data members (node class, int data, *left , *right) and have them at the same time protected, all-in-one. As you can see "newnode" just creates a node and NULL s the pointers. Thats it. "Find" searches and finds a node with a current key, and returns it when exits. All the rest, i guess, you can understand them, as they are prety much the same with your code. The only thing you have to do is to define, when you want to direct the node you want. REMINDER: You have to find a way to utilize it, so the leafs will not end far-left or far-right.("Enter the direction"). I hope i helped you understand.
#include <iostream>
#include <conio.h>
using namespace std;
class mybTree {
class node {
public:
int data;
node * left;
node *right;
};
node *root;
node *newnode(int num){
node *newnode1;
newnode1 = new (nothrow) node;
newnode1->data = num;
newnode1->left = NULL;
newnode1->right = NULL;
return newnode1;
}
public:
node *find (int key) {
node *current;
current = root;
while (current->data !=key){
if (key<current->data){
current = current->left;
} else {
current = current->right;
}
if (current == NULL){
return NULL;
}
}
return NULL;
}
void display (node *ptr);
void display_tree();
bool insert(int num);
void post_order_delete(node *ptr);
mybTree();
~mybTree();
};
int main(){
char ch = ' ';
int a;
mybTree mybTree1;
while (ch !='0'){
cout << "0->Exit"<<endl<< "1-> add"<<endl<< "2-> find" <<endl<<"3-> Show me the tree\n";
ch = getch();
switch (ch) {
case '0':
break;
case '1':
cout << "number";
cin >> a;
if (!mybTree1.insert(a)){
cout << "Not enough memory" << endl;
}
break;
case '2' :
cout << "Number:" ;
cin >> a;
if (mybTree1.find(a)!=NULL) {
cout << "Found" << endl;
} else {
cout << "Not existed" << endl;
}
break;
case '3':
mybTree1.display_tree();
cout<<endl;
break;
default:
cout << "Wrong Message";
break;
}
}
return 0;
}
void mybTree::display(node *ptr) {
if (ptr == NULL){
return;
}
display(ptr->left);
cout << ptr->data<<endl;
display(ptr->right);
}
void mybTree::display_tree() {
//Displays the Tree
display(root);
}
bool mybTree::insert(int num) {
//It inserts a node. Desides left or right.
node *next,*current,*ptr;
int isleft;
next = current = root;
ptr = newnode(num);
if (ptr == NULL) {
return false;
}
if (root == NULL) {
root = ptr;
return true;
}
while (1){
if (num < current->data){
next = current->left;
isleft = 1;
} else {
next = current->right;
isleft = 0;
}
if (next == NULL){
if (isleft){
current->left = ptr;
} else {
current->right = ptr;
}
return true;
}
current=next;
}
return false;
}
void mybTree::post_order_delete(node *ptr) {
//deletes the node. Usefull for destructor
if (ptr == NULL){
return;
}
post_order_delete(ptr->left);
post_order_delete(ptr->right);
cout << ptr->data;
delete ptr;
}
mybTree::mybTree() {
//Constructor
root = NULL;
}
mybTree::~mybTree() {
//Destructor
post_order_delete(root);
root = NULL;
}