Traversal In linked list - c++

I am new to linked list..My simple code is to create linked list and insert nodes at the end and traverse it..
My problems are-
1)-Every time insert function is called,head pointer gets null
2)-not working right while going in show function..
Please help..Thanks in advance
#include<iostream>
#include<malloc.h>
using namespace std;
struct linkedList
{
int value;
linkedList *next;
};
linkedList* head = NULL;
void insert(linkedList* head, int data)
{
linkedList *ptr;
linkedList *node;
node = (linkedList*) malloc(sizeof(struct linkedList));
node->value = data;
node->next = NULL;
if (head == NULL)
{
head = node;
}
else
{
ptr = head;
while (ptr != NULL)
{
ptr = ptr->next;
}
ptr = node;
}
}
void show(struct linkedList *head)
{
struct linkedList *ptr;
ptr = head;
while (ptr != NULL)
{
cout << ptr->value << endl;
ptr = ptr->next;
}
}
int main()
{
int size = 5;
int array[size];
for (int i = 0; i < 5; i++)
{
cout << "Enter value" << endl;
cin >> array[i];
insert(head, array[i]);
}
show(head);
}

In your insert() function:
when head is NULL, you are assigning the new node to the local head parameter, which is not updating the caller's head variable. That is why your global head variable is always NULL. This is because you are passing the head parameter by value, so you are assigning the new node to a copy, not the original. You need to pass the parameter by reference/pointer instead.
when head is not NULL, you are not traversing the nodes correctly to find the tail node, so ptr is always NULL after the traversal. You are not setting the next field of the tail node at all.
Also, your main() is leaking the allocated nodes.
Try something more like this instead:
#include <iostream>
struct linkedNode
{
int value;
linkedNode *next;
};
void insertValue(linkedNode* &head, int data)
{
linkedNode *node = new linkedNode;
node->value = data;
node->next = NULL;
if (!head)
{
head = node;
}
else
{
linkedNode *ptr = head;
while (ptr->next)
{
ptr = ptr->next;
}
ptr->next = node;
}
}
void showValues(linkedNode *head)
{
linkedNode *ptr = head;
while (ptr)
{
std::cout << ptr->value << std::endl;
ptr = ptr->next;
}
}
void freeValues(linkedNode* &head)
{
linkedNode *ptr = head;
head = NULL;
while (ptr)
{
linkedNode *next = ptr->next;
delete ptr;
ptr = next;
}
}
int main()
{
linkedNode* mylist = NULL;
for (int i = 0; i < 5; ++i)
{
std::cout << "Enter value" << std::endl;
int value;
if (std::cin >> value)
insertValue(mylist, value);
}
showValues(mylist);
freeValues(mylist);
return 0;
}
That being said, if you keep track of the tail node in the list, inserts at the end would be much faster and efficient since you would not need to traverse the list at all:
#include <iostream>
struct linkedNode
{
int value;
linkedNode *next;
linkedNode(int data)
value(data), next(NULL)
{
}
};
struct linkedList
{
linkedNode *head;
linkedNode *tail;
linkedList()
: head(NULL), tail(NULL)
{
}
~linkedList()
{
linkedNode *ptr = head;
while (ptr)
{
linkedNode *next = ptr->next;
delete ptr;
ptr = next;
}
}
void insert(int data)
{
linkedNode *node = new linkedNode(data);
if (!head)
head = node;
if (tail)
tail->next = node;
tail = node;
}
void showValues()
{
linkedNode *ptr = head;
while (ptr)
{
std::cout << ptr->value << std::endl;
ptr = ptr->next;
}
}
};
int main()
{
linkedList mylist;
for (int i = 0; i < 5; ++i)
{
std::cout << "Enter value" << std::endl;
int value;
if (std::cin >> value)
mylist.insert(value);
}
mylist.showValues();
return 0;
}
In which case, you could just throw all of this away and use the standard std::list class instead:
#include <iostream>
#include <list>
#include <algorithm>
void showValue(int value)
{
std::cout << value << std::endl;
}
void showValues(const std::list<int> &values)
{
std::for_each(values.begin(), values.end(), showValue);
/* or, if you are using C++11:
std::for_each(values.begin(), values.end(),
[](int value){ std::cout << value << std::endl; }
);
*/
}
int main()
{
std::list<int> mylist;
for (int i = 0; i < 5; ++i)
{
std::cout << "Enter value" << std::endl;
int value;
if (std::cin >> value)
mylist.push_back(value);
}
showValues(mylist);
return 0;
}

Related

Trying to initialize a linked list using array

I need to define a class of linked list,List, in a way such that object of class can be defined in two ways,
List obj1 = L1();//head=0
List obj2 = L2(given_arr[], size of array) // I would be given an array, whose elements are elements of list
so, I need to form a construter for both,
for obj1, Its easy.
List(){head=0};
But I am not abe to do so for second type of object.
I tried to form a program for this.
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head;
int arr[];
List() { head = 0; }
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
int i;
head->val = arr[0];
for (i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[4] = {9, 89, 0, 43};
List* M = new List();
List* L = new List(barr[4], 4);
L->display();
return 0;
}
This program doesn't work. Please suggest a way to do so.
Make these changes to your main().
int main() {
int barr[] = {9, 89, 0, 43}; // No need to specify size if you're initializing
// List* M = new List(); // unused
// Your array is barr, barr[4] makes no sense. You also don't allocate the List,
// the list allocates
List L = List(barr, sizeof(barr) / sizeof(barr[0]);
L.display(); // -> to .
return 0;
}
This now compiles, but immediately segfaults. Simply running the program in the debugger shows a simple error. The line head->val = arr[0]; attempts to dereference a null pointer. Which takes us to the next thing. Use nullptr, not NULL or 0.
Your array constructor was over-complicated, you just need this:
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
Your addnode() function already handled an empty list. Fixing that, your code should run. I made a couple other small changes, mostly trimming cruft out. Here's your complete code:
#include <iostream>
using namespace std;
class List {
class node {
public:
int val;
node* next;
};
public:
node* head = nullptr;
List() = default;
List(int arr[], int size);
void addnode(int value) {
node* newnode = new node();
newnode->val = value;
newnode->next = NULL;
if (head == NULL) {
head = newnode;
} else {
node* temp = head; // head is not NULL
while (temp->next != NULL) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void display() {
if (head == NULL) {
cout << "List is empty!" << endl;
} else {
node* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
}
};
List::List(int arr[], int size) {
for (int i = 0; i < size; i++) addnode(arr[i]);
}
int main() {
int barr[] = {9, 89, 0, 43};
List L = List(barr, sizeof(barr) / sizeof(barr[0]));
L.display();
return 0;
}

Displays reverse order but not the non-reverse order c++

It will not show the string char array in non-reverse order (cde), but it does display the array in reverse order (edc). Could you please help with why it isn't displaying the cde?
I tried changing variable names, but I'm a new programmer so I don't really know yet what to do.
#include <iostream>
using namespace std;
// of linked list in reverse order
// Structure of a node
template<class T>
struct listrec2
{
T value; //corresponds to data
listrec2 *next; //points to next node
listrec2 *prev; //points to previous nod
};
template<class T>
void downwardSearch(listrec2<T> *head)
//traverse from start of linked list to end of linked list
//print out value of each node along way
{
char s[] = { 'c', 'd', 'e' };
// if you wanted to make it in the function listrec2<T> *tail;
listrec2<T> *current;
listrec2<T> *tail;
listrec2<T> value;
head = tail = new listrec2<T>; // make a new node
head->value = s[0];
tail = NULL;
head = NULL;
for (int i = 1; i < strlen(s); i++)
{
current = new listrec2<T>; //makes new node
current->value = s[i];
current->next = NULL;
current->prev = tail;
tail->next = current;
tail = current;
}
listrec2<T> *ptr;
ptr = head;
cout << "The array in non-reverse order: " << endl;
while (ptr != NULL)
{
cout << ptr->value;
ptr = ptr->next;
}
}
template<class T>
void upwardSearch(listrec2<T> *tail)
{
char s[] = { 'c', 'd', 'e' };
// if you wanted to make it in the function listrec2<T> *tail;
// listrec2<T> *temp;
listrec2<T> *current2;
listrec2<T> *tail2;
listrec2<T> *value;
listrec2<T> *head2;
head2 = tail = new listrec2<T>; // make a new node
head2->value = s[0];
tail2 = NULL;
head2 = NULL;
for (int i = 1; i < strlen(s); i++)
{
current2 = new listrec2<T>;
current2->value = s[i];
current2->next = NULL;
current2->prev = tail;
tail->next = current2;
tail = current2;
}
listrec2<T> *ptr2;
ptr2 = tail;
cout << "The array in reverse order or backwards: " << endl;
while (ptr2 != NULL)
{
cout << ptr2->value;
ptr2 = ptr2->prev;
}
cout << endl;
}
int main()
{
//missing info here
listrec2<char> *head;
listrec2<char> *tail;
upwardSearch(head);
downwardSearch(tail);
return 0;
}
The expected results are: the array before reversal: cde
the array after reversa: edc.
Here is one way of doing it with a create_list, search_up, search_down, and destory_list functions. I try to use variable names that are more descriptive. I do not like listrec2 because it is very confusing. It makes me think of the second node, but that is not what it is. It is a node type.
Also, it is a good habbit to capitalize your types (e.g. Node). Then, you can use the lowercase version for the object (e.g. Node node;)
#include <iostream>
using namespace std;
// of linked list in reverse order
// Structure of a Node
template<class T>
struct Node {
T value; //corresponds to data
Node *next; //points to next Node
Node *prev; //points to previous nod
};
template<typename T>
void CreateList(Node<T> *&head, Node<T> *&tail, T value_array[], int array_size)
{
head = nullptr;
tail = nullptr;
for (int i = 0; i < array_size; i++) {
// Create new node and add node to the end of the list
Node<T> *node = new Node<T>();
node->next = nullptr;
node->prev = tail;
if (head == nullptr) {
head = tail = node;
} else {
tail->next = node;
tail = node;
}
node->value = value_array[i];
}
}
template<class T>
void downwardSearch(Node<T> *head)
//traverse from start of linked list to end of linked list
//print out value of each Node along way
{
Node<T> *ptr = head;
cout << "The array in forward order: " << endl;
while (ptr != nullptr) {
cout << ptr->value;
ptr = ptr->next;
}
}
template<class T>
void DestroyList(Node<T> *head)
{
Node<T> *ptr;
while (head != nullptr) {
ptr = head->next;
delete head;
head = ptr;
}
}
template<class T>
void upwardSearch(Node<T> *tail)
{
Node<T> *ptr = tail;
cout << "The array in reverse order or backwards: " << endl;
while (ptr != nullptr) {
cout << ptr->value;
ptr = ptr->prev;
}
cout << endl;
}
int main()
{
char s[] = {'c', 'd', 'e'};
Node<char> *head;
Node<char> *tail;
CreateList<char>(head, tail, s, 3);
upwardSearch(tail);
downwardSearch(head);
DestroyList(head);
head = tail = nullptr;
return 0;
}

What's the reason of the linked list has a zero beginning of the beginning? C++

#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
void add(struct Node *head, int n) {
Node *newNode = new Node;
newNode->data = n;
newNode->next = NULL;
Node *cur = head;
while(cur) {
if(cur->next == NULL) {
cur->next = newNode;
return;
}
cur = cur->next;
}
}
void display(struct Node *head) {
Node *list = head;
while(list) {
cout << list->data << " ";
list = list->next;
}
cout << endl;
cout << endl;
}
int main()
{
struct Node *newHead;
struct Node *head = new Node;
int ar[]={2,5,46,7,55};
for(int i=0; i<5;i++){
add(head,ar[i]);
}
display(head);
}
OUTPUT:
0 2 5 46 7 55
What's the reason of the linked list has a zero of the beginning?
And how can I fix it? I do not want to print zero.
If you see some mistakes in my code, please tell me. I am new at coding.
In main, you allocate an uninitialized instance of Node and store the pointer in head. You never assign the head->data of that node, so that value is indeterminate. Same holds for head->next. When those values are read in add and display, the behaviour of the program is undefined.
And how can I fix it?
Firstly, initialize head in main to avoid undefined behaviour:
Node *head = new Node();
// ^^ these are important
Then you could do one of these things:
a) Skip the first node using display(head->next); instead of display(head);
b) Initialize the head to the first value that you want
head->data = ar[0];
for(int i=1; i<5;i++)
// ...
c) Redesign your API to not require the user to allocate the first node separately. More details about this in Remy's answer.
There are several problems with your code:
When you allocate the head node, you are not assigning any value to its data member, so it holds a random value that happens to be 0 in your case. And you are not initializing its next member either, which means add() and display() will not work correctly.
in add(), if head is NULL, no node is added to the list (you don't update the caller's Node* variable to point at the new node), and you leak the allocated newNode.
you are leaking all of the allocated nodes when exiting from main().
Try this instead:
#include <iostream>
struct Node {
int data;
Node* next;
Node(int value) : data(value), next(0) {}
};
void add(Node* &head, int n) {
Node **newNode = &head;
while (*newNode) {
newNode = &((*newNode)->next);
}
*newNode = new Node(n);
}
void display(Node *head) {
Node *cur = head;
while (cur) {
std::cout << cur->data << " ";
cur = cur->next;
}
std::cout << std::endl;
std::cout << std::endl;
}
void clear(Node* &head) {
Node *cur = head;
head = NULL;
while (cur) {
Node *next = cur->next;
delete cur;
cur = next;
}
}
int main()
{
Node *head = NULL;
int ar[] = {2, 5, 46, 7, 55};
for(int i = 0; i < 5; ++i){
add(head, ar[i]);
}
display(head);
clear(head);
return 0;
}
And then, when you get that working, throw it all away and use the STL's std::list container instead:
#include <iostream>
#include <list>
void display(const std::list<int> &mylist) {
for(std::list<int>::const_iterator iter = mylist.begin(); iter != mylist.end(); ++iter) {
std::cout << *iter << " ";
}
std::cout << std::endl;
std::cout << std::endl;
}
int main()
{
std::list<int> mylist;
int ar[] = {2, 5, 46, 7, 55};
for(int i = 0; i < 5; ++i){
mylist.push_back(ar[i]);
}
/* or:
int ar[] = {2, 5, 46, 7, 55};
std::list<int> mylist(ar, ar+5);
*/
display(mylist);
return 0;
}

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

What are self referential C++ types good for?

What are use cases for self-referential types?
By self referential types, I mean:
class T {
T *ptr; // member variable that references the type of the class
};
It is one of the most efficient ways to build linked lists or tree
hierarchies.
#include <iostream>
class linked_ints {
public:
linked_ints() : next(nullptr), x(0) {}
linked_ints* next;
int x;
};
void print(linked_ints* b) {
if(b == nullptr) return;
do {
std::cout << b->x << std::endl;
} while((b = b->next));
}
int main()
{
linked_ints x, y, z;
x.next = &y; y.next = &z;
print(&x);
return 0;
}
One example I can think of are linked lists.
The example borrowed from here:
#include<iostream>
struct Node{
int data;
Node* next;
};
void InsertAfter(Node **head, int value){
if(*head==NULL){
Node* temp=NULL;
temp = new Node;
temp->data = value;
temp->next = NULL;
*head = temp;
}else{
Node *temp = new Node;
temp->data = value;
temp->next = (*head)->next;
(*head)->next = temp;
}
}
void DeleteAfter(Node **head){
if(*head==NULL){
return;
}else{
Node *temp = NULL;
temp = (*head)->next;
(*head)->next = (*head)->next->next;
delete temp;
temp=NULL;
}
}
int DeleteAll(Node **head,int value){
int count=0;
Node *p = NULL;
Node *q = (*head);
if(*head==NULL){
count =0;
}else{
while((q)!=NULL){
if((q)->data==value){
Node *temp = NULL;
temp = q;
if ( p!=NULL){
p->next = q->next;
}else{
(*head) = q->next;
}
q = q->next;
delete temp;
temp = NULL;
++count;
}else{
p = q;
q = q->next;
}
}
}
return count;
}
void DisplayList(Node *head){
if(head!=NULL){
std::cout << head->data << "\n";
while(head->next!=NULL){
std::cout << head->data << "\n";
head =
head->next;
}
std::cout << "\n\n";
}
int main(){
Node *head=NULL;
InsertAfter(&head,10);
InsertAfter(&head,10);
InsertAfter(&head,20);
InsertAfter(&head,10);
DisplayList(head);
DeleteAfter(&head);
DisplayList(head);
int a = DeleteAll(&head,10);
std::cout << "Number Of Nodes deleted
having value 10 = " <<
a <<"\n\n";
DisplayList(head);
return 0;
}