I have recently started learning data structure and as a beginner, I have a query while implementing linked list nodes, why do we have to initialize node using a pointer only?
class node{
public:
int data;
node* next;
node(int val){
data = val;
next = NULL;
}
};
int main(){
node* head = NULL;
node head = NULL; // this throws an error which i cannot understand
}
Actually you can initialize the node by value. If you want to initialize a node with value, according to your constructor node(int val), you have to code like below:
class node{
public:
int data;
node* next;
explicit node(int val){
data = val;
next = NULL;
}
};
int main(){
int value = 777;
//node* head = NULL; // Initialize head pointers to null
node head(value); // By your constructor definition
}
EDIT: By the way, marking a constructor as explicit is a very good habit to have, as it prevents unexpected conversion, as Duthomhas commented.
Related
class Node
{
public:
int value;
Node *next;
};
class LinkedList
{
private:
Node *head;
public:
LinkedList(void) { head = NULL; }
~LinkedList(void){};
void insertAtHead(int);
void insertAtLocation(int, int);
void Delete(int);
void displayList();
int countList();
};
void LinkedList::insertAtHead(int new_value)
{
struct Node *newNode, *NodePtr = head;
newNode = new Node;
newNode->value = new_value;
newNode->next = NULL;
if (!head)
head = newNode;
else
{
newNode->next = NodePtr;
head = newNode;
}
cout << "Node successfully inserted at the head\n\n";
}
I didn't create any structure for the node, rather I made a class for it. But I don't know why my code is working properly when I make a newNode in the insertAtHead function by writing struct at the start of initialization, What is happening there? no, compile and run time error when the struct is written before Node. What is the concept behind this work?
There is no difference between struct and class that is relevant to this code. So you can switch them around as you wish with no consequences.
This
struct Node *newNode, *NodePtr = head;
is a C-ism. In C++ you would write:
Node *newNode, *NodePtr = head;
Moreover a struct is a class in C++. struct and class are just two different keywords. Only for default access they make a difference when used to define a class. See here for more details on that: When should you use a class vs a struct in C++?.
When I create a Node for Linked List, Stack, Queue, Trees, etc.
I have to create the NODE using
Node* x = new Node()
But instead, we can create the object for the Linked List, etc. using
LinkedList x;
for
class Node {
int data;
Node* next;
};
class LinkedList {
Node* head = NULL;
int size = 0;
bool push();
int pop();
};
please help. I am getting segmentation fault when i try to print elements in this linked list.
i first declare a class and the function to insert and display the elements of the list are its functions.
code:
#include <iostream>
using namespace std;
struct node{
int data;
node *next;
};
class ll{
node *head,*tail;
public:
void push(int x){
node *temp = new node;
temp->data = x;
temp->next = NULL;
if(head == NULL){
head = temp;
tail= temp;
}
else{
tail->next = temp;
tail= temp;
}
}
void show(){
node *n = head;
while(n!=NULL){
cout<<n->data<<"\n";
n = n->next;
}
}
};
int main()
{
ll a;
a.push(1);
a.push(2);
a.show();
return 0;
}
Neither the data member head nor the data member tail are initialized by nullptr. So the program has undefined behavior.
You could write in the class definition
class ll{
node *head = nullptr, *tail = nullptr;
//...
Bear in mind the structure node should be member of the class ll. For example
class ll{
struct node{
int data;
node *next;
} *head = nullptr,*tail = nullptr;
public:
void push( int x ){
node *temp = new node { x, nullptr };
if( head == NULL ){
head = tail = temp;
}
else {
tail = tail->next = temp;
}
}
//...
Instead of initializing data members in the class definition you coudl initialize them in the default constructor like for example
class ll{
struct node{
int data;
node *next;
} *head,*tail;
public:
ll() : head( nullptr ), tail( nullptr ) {}
// ...
Also you need at least to define the destructor and either explicitly define the copy constructor and copy assignment constructor or define them as deleted. For example
class ll{
struct node{
int data;
node *next;
} *head,*tail;
public:
ll() : head( nullptr ), tail( nullptr ) {}
~ll() { /* must be defined */ }
ll( const LL & ) = delete;
ll & operator =( const ll & ) = delete;
// ...
The problem is that you don't set head to NULL when you list is created. Same issue applies to tail. This is a job for the constructor
class ll {
node *head,*tail;
public:
ll() { head = tail = NULL; }
void push(int x) {
...
On geeks for geeks I saw a different way to create the Node for linked list.
struct Node{
int data;
Node* next;
Node(int x){
data = x;
next = NULL;
}
}
Can someone please explain me how that node is defined.
struct Node {
int data;
Node *next;
Node(int x) : data(x), next(NULL) {}
};
This is just a way to define structure with constructor in C++
You can use them simply like this
Node *node = new Node(4);
I'm trying to implement a singly linked list on my own in C++ from scratch, having got so far with my first method append():
#include <iostream>
using namespace std;
struct ListNode{
int key_value;
ListNode *next;
};
class List{
public:
List();
void append(int key);
private:
ListNode *head;
ListNode *tail;
};
List::List(){
head = NULL;
tail = head;
}
void List::append(int key){
ListNode *newnode;
newnode->key_value = key;
newnode->next = NULL;
if(head == NULL){
head = newnode;
tail = head;
}
else{
tail->next = newnode;
tail = newnode;
}
return;
}
int main(){
try{
List l1;
l1.append(1);
//l1.append(2);
//l1.append(3);
//l1.append(5);
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
It compiles without any warnings or errors, but during execution I'm only getting the message Bus error: 10. Seems there is something wrong with the way I'm initializing and using the ListNode variables and pointers, any insights would be appreciated.
In this line:
ListNode *newnode;
you create uninitialized variable of pointer to ListNode and then you dereference it. Any access to unintialized variable leads to UB, but with pointers you most probably will get bus error immediatly. So allocate memory:
ListNode *newnode = new ListNode;
Note: instead of initializing data members:
newnode->key_value = key;
newnode->next = NULL;
you should provide proper constructor for ListNode:
struct ListNode {
int key_value;
ListNode *next;
ListNode( int v ) :
key_value( v ),
next( nullptr )
{
}
};
then just create it:
ListNode *newnode = new ListNode( key );
and next 2 lines can be omitted. This will make your code cleaner and prevent from creating a ListNode instance with uninitialized data.
Note N2: as your class List has a raw pointer and ownership of the data you should follow rule of three and create or disable copy ctor, assignment operator and dtor.