I am trying to make a linked list for my C++ class and I was looking at some code from my professor:
void List::add(char c)
{
Node *newNode(new Node(c));
if (last == nullptr)
first = last = newNode;
else {
last->next = newNode;
last = newNode;
}
}
int List::find(char c)
{
Node *node(first);
int i(0);
while (node) {
if (node->c == c)
return i;
node = node->next;
i++;
}
return -1;
The following is the class declaration from the header file:
class List
{
public:
List(void);
~List(void);
void add(char c);
int find(char c);
bool remove(int index);
int length(void);
friend std::ostream& operator<<(std::ostream& out, List& list);
private:
class Node
{
public:
Node(char c) : c(c), next(nullptr) { }
char c;
Node *next;
};
Node *first;
Node *last;
};
First question: what do the parentheses mean and what is the correct way to use them?
Node *newNode(new Node(c));
Node *node(first);
int i(0);
Second question: What does the following mean?
Node(char c) : c(c), next(nullptr) { }
I have defined a node in the past using a struct; is the syntax different because this is a class?
This statements
Node *newNode(new Node(c));
Node *node(first);
int i(0);
are equivalent to
Node *newNode = new Node(c);
Node *node = first;
int i = 0;
This constructor of the class Node
Node(char c) : c(c), next(nullptr) { }
uses mem-initializer list : c(c), next(nullptr) to initialize data members of the class.
That is data member c is initialized by constructor parameter c and data member next is initialized by pointer literal nullptr
Related
struct Node {
int data;
Node* next;
Node* prev;
Node() : data(0), next(nullptr), prev(nullptr) { }
explicit Node(int elt) : data(elt), next(nullptr), prev(nullptr) { }
};
class DequeEmptyException { };
class Deque {
public:
Deque();
~Deque();
Deque(const Deque& orig);
Deque& operator=(const Deque& rhs);
private:
Node* head;
Node* tail;
int length;
void copy(const Deque& source, Deque& destination);
};
here are is my copy constructor from source to destination.
void Deque::copy(const Deque& source, Deque& destination) {
// create dummy header
destination.head = new Node;
destination.head->next = destination.head->prev = destination.head;
// copy nodes
for (Node *p = source.head->next; p != source.head; p = p->next) {
Node *t = new Node;
t->data = p->data;
// insert at end of list
t->next = destination.head;
t->prev = destination.head->prev;
t->prev->next = t;
t->next->prev = t;
}
source.length = destination.length;
}
This is my attempt. Does it look correct as there are many other implementations within the Deque that I was unable to show. This was the most confusing.
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) {
...
I'm trying to implement a linked list class in C++ using a node class and a pointer to the next node.
template<class T>
class Node {
public: T val;
public: Node* next;
public: Node() { }
public: Node(T val) { this.val = val; }
};
I created a linked list class with a pointer to the head and a function append to add nodes to the list:
template<class T>
class LinkedList {
private: Node<T>* head;
public: LinkedList() { }
public: LinkedList(T val) { head -> val = val; }
public: void append(T val) {
Node<T>* temp = head;
while(temp -> val != NULL) {
temp = temp -> next;
}
temp -> val = val;
}
};
but after compilation and running, it throws this error "Segmentation fault (core dumped)"
I know a little about segmentation fault like trying to access a memory location that is no longer existed but I don't get it in this example, any help??
The main problem is that you don't initialize the next pointer with null pointer, but you assume it is null pointer by default. Here's how you fix it:
template <class T>
class Node {
public:
T val;
Node* next;
Node( T val_ = {} )
: val{ val_ }
, next{ nullptr }
{ }
};
Besides that, in the append there are problems. Here's how the code should have looked like completely:
template <class T>
class Node {
public:
T val;
Node* next;
Node(T val_ = {}) : val{ val_ }, next{ nullptr } {}
};
template <class T>
class LinkedList {
private:
Node<T>* head;
public:
LinkedList(T val_ = {}) : head{ new Node{val_} } {}
void append(T val) {
Node<T>* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = new Node<T>{ val };
}
};
int main() {
LinkedList<int> l;
l.append(10);
}
Other comments:
this.val won't compile, because this is a pointer. You meant this->val.
You should consider using member initializer lists instead of this->val = val.
Initialize all members in all constructors.
When I call the function createBst(), the program gets terminated in the function.
I put a print statement after the function but it is not called.The next print statement "terminated" is not called
int main(){
bst b;
b.createBst();
std::cout<<"terminated"<<std::endl;
return 0;
}
class node{
public:
int val;
node* left;
node* right;
};
class bst{
public:
node* head;
void createBst();
node* newNode(int val);
};
node* bst::newNode(int v){
node n1;
node* n=&n1;
n->val=v;
n->left=nullptr;
n->right=nullptr;
return n;
}
void bst::createBst(){
head=bst::newNode(10);
head->left=bst::newNode(11);
(head->left)->left=bst::newNode(7);
head->right=bst::newNode(9);
(head->right)->left=bst::newNode(15);
(head->right)->right=bst::newNode(8);
}
the output should be "terminated".
For starters the classes shall be defined before their usage in main.
This function
node* bst::newNode(int v){
node n1;
node* n=&n1;
n->val=v;
n->left=nullptr;
n->right=nullptr;
return n;
}
invokes undefined behavior because it returns pointer ro a local variable n1 that will not be alive after exiting the function.
The function could be defined the following way
node* bst::newNode(int v)
{
return new node { v, nullptr, nullptr };
}
In fact the function can be a private static member function
class bst{
public:
node* head;
void createBst();
private:
static node* newNode(int val);
};
And the class node should be a nested private (or protected) class of the class bst.
Also you need either a default constructor for the class bst that will initialize head to nullptr or you have to explicitly initialize head to nullptr in the class definition like
class bst{
public:
node* head = nullptr;
void createBst();
private:
static node* newNode(int val);
};
To insert a data into the tree you should write a function for example like this
void insert( int value )
{
node **current = &head;
while ( *current != nullptr )
{
if ( value < ( *current )->val )
{
current = &( *current )->left;
}
else
{
current = &( *current )->right;
}
}
*current = newNode( value );
}
I was working for writing a copy constructor for List class with requirement as not to use any other methods in implementation.
The class fragment is as follows :
class List {
private:
struct Node {
NodeData *data;
Node *next;
};
Node *head;
};
The requirement is to write copy constructor for this class and do not use any other methods in implementation except that we may use copy constructor for NodeData class
I have written the copy constructor as follows:
list::list(const list &t){
Node* q;
q=new Node;
while (p!=NULL){
q->x= p->x;}
}
This is not working, please help in how to write the copy constructor as required.
I disagree with the commentors that this is a moronic exercise, actually its interesting to try and do this. The following should give you an idea on what to try: http://ideone.com/DdC7bN
class List {
private:
struct Node {
int data; // simplification
Node *next;
Node(int d) {
data = d;
next = NULL;
}
};
protected:
Node *head;
Node *tail;
public:
List(int d) : head(new Node(d)), tail(head) {}
void append(int d) {
Node* n = new Node(d);
tail->next = n;
tail = n;
}
List(const List& rhs) {
if (head) delete head;
head=new Node(rhs.head->data);
Node* lhsCurrent = head;
Node* rhsCurrent = rhs.head->next;
do {
lhsCurrent->next = new Node(rhsCurrent->data);
rhsCurrent = rhsCurrent->next;
lhsCurrent = lhsCurrent->next;
} while (rhsCurrent!=NULL);
tail = lhsCurrent;
}
};
int main() {
List first(5);
first.append(6);
List second(first);
return 0;
}