Find the first element in list. C++ - c++

this is my program for list implementation in C++. And want to print the first element in it.
I write element until I reach 0
Can You show me the way to do it. Thanks
#include "stdafx.h"
#include "iostream"
using namespace std;
struct Node {
int data;
Node *next;
};
int main()
{
Node *first = 0;
Node *p;
cout << "Enter a list" << endl;
int i;
while (true) {
cin >> i;
if (i == 0) break;
p = new Node;
p -> data = i;
p -> next = first ;
first = p;
}
cout << "List: ";
p = first;
while (p) {
cout << p -> data;
p = p -> next;
}
cout << endl;
return 0;
}

Your program has a problem with keeping the initial element of the list: the code that you have assigns the last element to the variable called first, so your second loop will end as soon as it starts.
You need to change the logic around assigning first: for example, rather than assigning it unconditionally, you could assign it only if it is 0:
if (first == 0) {
first = p;
}
In addition to fixing this, you should add code to free the objects that you allocate with new. Use delete to free up the nodes in the list. This can be done in the same way as your second loop:
p = first;
while (p) {
Node* tmp = p;
p = p -> next;
delete tmp;
}

What you created is a stack (LIFO). You are adding new elements to its top, so first actually points to the last added element when you are traversing the data structure.
So, you can traverse it till the element's next is NULL - that's your actual first element.
Or you can change your program to use a different data structure, where you add elements to the tail and not to the head, or where you keep a pointer to the first element.

Just visit your linked list until you hit a node whose next pointer is 0.
This is the first node. Print its value and you are done.
Keep a pointer on the last node to be able to traverse the linked list.
If you need that first node often, keep an extra pointer for it.

Related

Random access of a linked list element

In an article about linked list, it is said that accessing a random element is not allowed and to access a certain node we need to traverse it from the head node
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
};
// This function prints contents of linked list
// starting from the given node
void printList(Node* n)
{
while (n != NULL) {
cout << n->data << " ";
n = n->next;
}
}
// Driver code
int main()
{
Node* head = NULL;
Node* second = NULL;
Node* third = NULL;
// allocate 3 nodes in the heap
head = new Node();
second = new Node();
third = new Node();
head->data = 1; // assign data in first node
head->next = second; // Link first node with second
second->data = 2; // assign data to second node
second->next = third;
third->data = 3; // assign data to third node
third->next = NULL;
printList(head);
return 0;
}
This was the example code on traversing a linked list and printing it's values
If i change the argument of printList() to second, it would still work
My question is, did i misinterpret the meaning to "access an element of a linkedlist", what does an element of a linkedlist contain?
I think you overinterpreted the article. You should store in your program only pointer to the first element (head) and in that case, you are not able to access n-th element directly. You need to find it "manually" by jumping to "next" element (n-1) times.
It doesn't mean that you are not able to access n-th element if you have pointer to that element.
accessing a random element is not allowed
That statement isn't quite precise about linked lists.
What is true is that given a linked list (and nothing more), it isn't possible find an element at any given index in constant time.
However, if you have an iterator or a reference to an element of a list, you can access that element in constant time through the iterator / reference.
To clear your confusion we probably should add the example of an array
Say we have an array
[1,2,3,4,5]
and a linkedlist
1->2->3->4->5
now if you want to access the 5th element in both the data structure what can you do
for array you just have to access the array[4] to get the element which is a O(1) operation to get the element
but for linkedList this doesn't happen
for accessing the 5th element of the linkedList you ll have to iterate in a manner like this
int element = 5;
while(element--){
head = head->next;
}
and when the loop ends you ll get your element

std::list push back adds two elements instead of one

I'm trying to add elements to a list, but can't figure out why the push_back method is repeating the last added element. To illustrate:
Each node object consists of a data and head field. In the code below, I iterate through an array of ints, create a new node to store each int, and push_back the element to the list L. The repeated node is always the last one added to the list (in the picture above when iteratror i=1)
void addElements(std::list<node>& L, int arr[],std::list<node>::iterator Itor,int size){ //array decays to pointer
for (int i=1;i<size;i++){
node* n = new node;
n->data = arr[i];
n->head = Itor->head; //head of the first element in the list
L.push_back(*n);
}
}
I included the complete code of the disjoint data structure below. I read on cplusplus.com that push_back increases the container size by 1. So I'm a little perplexed why an extra node is being added to the list.
#include <iostream>
#include <list>
struct node{
int data;
node* head;
};
void makeSet(std::list<node>& L,int arr[]){ //asterick is before the variable name
node *headNode = new node;
headNode->data = arr[0]; //representative node
headNode->head = headNode; //point to itself
L.push_back(*headNode);
}
void addElements(std::list<node>& L, int arr[],std::list<node>::iterator Itor,int size){ //array decays to pointer
for (int i=1;i<size;i++){
node* n = new node;
n->data = arr[i];
n->head = Itor->head; //head of the first element in the list
L.push_back(*n);
}
}
int findSet(node* element){
return element->head->data;
}
int main(int argc, const char * argv[]) {
std::list<node>List;
std::list<node>::iterator Itor;
int dataArr[]={1,2,3,4,5};
int size = sizeof(dataArr)/sizeof(dataArr[0]);
Itor = List.begin();
makeSet(List,dataArr);
addElements(List,dataArr,Itor,size);
for (Itor = List.begin();Itor!=List.end();Itor++){
std::cout << Itor->data << std::endl;
}
}
Note that the size of the list in your example is 2. This means only nodes 0 and 1 are valid. This extra duplicate link is likely a Sentinel Value.
Often you'll find linked lists terminate with a null pointer, but it's just as easy to define the end of the list as a link that points to itself. This may have additional advantages, such as providing a one-past-the-end link to return as list::end.
Whatever its benefits, it is outside the bounds of the list so best that you not mess with it.

traversing a doubly-linked list and insert at its end (C++)

I have to face this problem: I have a doubly linked list and I have to make insertion at the tail. My list is made of Nodes such as
struct Node {
int val; // contains the value
Node * next; // pointer to the next element in the list
Node * prev; // pointer to the previous element in the list
};
and my class list declares only
private:
Node * first; // Pointer to the first (if any) element in the list
at first.
Now, I wrote such a method for inserting:
void List::insert(int n){
Node * tmp = new Node;
tmp->val = n;
tmp->next = 0;
if (!first) {
first = tmp;
}
else {
Node * p = new Node;
p = first;
while (p->next) {
p = p->next;
}
p->next = tmp;
tmp->prev = p;
}
};
and if I take several numbers from cin (say, 1 2 3 4), I call insert but I end up not having all the elements I wanted to store. I have only first and tmp, which contains the last number from the input (e.g. 4).
I struggle to figure out what's wrong - my first suggestion is variable scope.
Or is there anything wrong during the pointer setting?
OBS: I'd use a tail pointer of course, but the aim is traversing the list.
Any feedback is really appreciated.

C++ Linked List – a new pointer that is not used to traverse the list CAN print the list?

I created a simple dynamic linked list implementation in C++ which has a head node of 42, and after which, prompts the user if he/she wants additional numbers to add to the list.
#include <iostream>
using namespace std;
struct Node
{
int x;
Node *next;
};
int main(int argc, char** argv)
{
char choice;
Node *start = new Node;
start->next = NULL;
start->x = 42;
Node *traverser = start;
while (1) {
cout << "Add item to the list (Y/N)? ";
cin >> choice;
if (choice == 'Y') {
traverser->next = new Node;
traverser = traverser->next;
traverser->next = NULL;
cout << "New item: ";
cin >> traverser->x;
}
else {
cout << "Linked List:\n";
Node *p;
for (p = start; p != NULL; p = p->next) {
cout << p->x << endl; //QUESTION HERE!
}
cout << "\nProgram dismissed.";
exit(0);
}
}
}
Now the question, as indicated in the code block, lies on the pointer *p. The head of my linked list is named start, while the pointer that traverses and adds items to the list is named traverser. Why the heck is *p able to print all that's in the list when it is only assigned to the head
p = start
and not to the body of the list. I would've understood that this works for printing
cout << "Linked List:\n";
for (traverser = start; traverser != NULL; traverser = traverser->next) {
cout << traverser->x << endl;
}
But *p being able to print the whole list confused me, a lot!
Please help.
*p is able to print the whole list, because *p (initially) points to the start of the list. After the start of the list, comes the body of the list, that you linked with
if (choice == 'Y') {
traverser->next = new Node;
traverser = traverser->next;
traverser->next = NULL;
cout << "New item: ";
cin >> traverser->x;
}
Understand here, that initially traverser and start both manipulate the same object. To put it in layman's terms, when you're using pointers, you're not cloning values, you're cloning instructions on how to access the values. Perhaps this was the source of your confusion?
So, the Node* start points to a node. Node* traverse points to the same node, as you declared Node *traverser = start; You could manipulate the value of the node in question via traverse->x or start->x, and get the exact same result.
p is just a pointer variable, like any other variable it can have different values , but it points to addresses.
p = start
p starts pointing toward your first node.
p = p->next
it starts pointing towards next node.
Where are you confused ?
traverser does not contain the body of the list. startdoes.
Let's review the contents of your program:
Node *start = new Node;
start will always point to the node created here. start is always the beginning of the list.
From this node you can travel through the entire list using the nodes next member.
Node *traverser = start;
traverser is initially the same node as the start node. traverser indicates the end of the list. You can't use traverser to travel through the list. The reason traverser is used is that it simplifies the insertion of a new node at the end of the list.
The last statement is shown by the statements
traverser->next = new Node;
traverser = traverser->next;
traverser->next = 0;
The last statement tells us that we can't follow the traverser node anywhere. This is the end of the list.
So startis the entire list, start->x is the first value in the list. start->next is a pointer to the next element in the list.
Now, we don't want to corrupt the startof the list. So let's make a copy of the pointer to the first element, and call that copy p. Use p to look through the list. p is only useful for this small section of the code, whereas start and traverser is useful for the entire program.
Node* p = start;
for (; p != NULL; p = p->next) {
cout << p->x << endl;
}
The last element printed will be the same element as traverserpoints to.

Trying to understand pointers and double pointers

I'm trying to implement a simple linked list in C++. I can create nodes and they seem to link themselves correctly. My question involves the listIterate() function, but I've attached the entire code here in case it is needed.
#include <iostream>
using namespace std;
//Wrapper class which allows for easy list management
class LinkedList {
//Basic node struct
struct node {
int data;
node *link;
};
node *head; //Pointer to the head (also referred to as root) node, or the first node created.
node *current; //Pointer to the /latest/ node, or the node currently being operated on.
node *tail; //Pointer to the tail node, or the last node in the list.
public:
//Default constructor. Creates an empty list.
LinkedList() {
head = NULL;
current = NULL;
tail = NULL;
cout << "*** Linked list created. Head is NULL. ***\n";
}
//Default destructor. Use to remove the entire list from memory.
~LinkedList() {
while(head != NULL) {
node *n = head->link;
delete head;
head = n;
}
}
/*
appendNode()
Appends a new node to the end of the linked list. Set the end flag to true to set the last node to null, ending the list.
*/
void appendNode(int i) {
//If there are no nodes in the list, create a new node and point head to this new node.
if (head == NULL) {
node *n = new node;
n->data = i;
n->link = NULL;
head = n;
//head node initialized, and since it is ALSO the current and tail node (at this point), we must update our pointers
current = n;
tail = n;
cout << "New node with data (" << i << ") created. \n---\n";
} else {
//If there are nodes in the list, create a new node with inputted value.
node *n = new node;
n->data = i;
cout << "New node with data (" << i << ") created. \n";
//Now, link the previous node to this node.
current->link = n;
cout << "Node with value (" << current->data << ") linked to this node with value (" << i << "). \n---\n";
//Finally, set our "current" pointer to this newly created node.
current = n;
}
}
/*
listIterate()
Iterates through the entire list and prints every element.
*/
void listIterate() {
//cursor
node *p;
//Start by printing the head of the list.
cout << "Head - Value: (" << head->data << ") | Linked to: (" << head->link << ") \n";
p = head->link;
cout << *p;
}
};
int main() {
LinkedList List;
List.appendNode(0);
List.appendNode(10);
List.appendNode(20);
List.appendNode(30);
List.listIterate();
}
Now, I'll refer to this method, listIterate().
void listIterate() {
//cursor
node *p;
//Start by printing the head of the list.
cout << "Head - Value: (" << head->data << ") | Linked to: (" << head->link << ") \n";
p = head->link;
cout << *p;
}
The command cout << *p; throws an error and I believe this is why: At this point, p is pointing to head->link, which is another pointer which points to the link field of my head node. Now, I understand if I dereference p at this point in the program, there would be no actual value in head->link as it points to a variable.
To me, if I dereference p twice (**p), it should follow the pointer twice (p -> head->link -> The value of the second node in the linked list (10). However, dereferencing p twice throws this error.
LinkedListADT.cc:89: error: no match for ‘operator*’ in ‘** p’
Can anyone help me understand why this is the case? Is this an illegal operation? Is it performed in another way that I'm not familiar with?
cout << *p tries to print a node object. Since no print operation is defined for node objects (ie. no operator<< for output streams), the attempt to print it fails. What you're probably looking for is:
cout << p->data;
For your second point, the statement can be broken down thus:
**p == *(*p)
So the first star dereferences p, returning a node. The second star attempts to dereference the result of that operation, but since a node is a struct and not a pointer, the compiler complains.
Hope this helps.
Your node class is missing an operator *, so the construct **p when p is of type node * is semantically ill-formed. To look at an example of overloading operator *, look at examples of implementing smart pointers.
**p Does not "follow the pointer twice". The operation simply tries to dereference p twice.
p is a pointer to a node. The first dereference (*p) will evaluate to the node that was pointed to by p. The second dereference (**p) will cause an error, because a node is a struct and not a pointer and has no overloaded operator* defined.
If you wish to dereference the pointer to the next node:
*(p->link)