I have a node in a linked list defined as:
class Node {
public:
Node* next = nullptr;
int value;
};
I am inserting nodes into the list as:
void insertNode(Node* &head, int value) {
Node* newNode = new Node;
newNode->value = value;
newNode->next = head;
head = newNode;
}
I want to remove some node in that list in another function
void deleteNode(Node* head) {
// ...
}
How can I remove that now unused node from memory?
You'd remove a node by 1) deleteing it. 2) adjusting the previous node to point to the one following the deleted node (or nullptr if the deleted node was the last one).
Related
I have a linked list and I need to insert a node at the location where the "iterator" is.
below is the insert function(which i have templated):
template <class T>
void List<T>::insert(T x)
{
if (size=0)
{
cout << "adding postion to head because empty list" << endl;
NodeRef newNode = new Node(x);
tail = head = newNode;
}
else
{
NodeRef temp = new Node(x);
temp->previous = iterator;
iterator->next = iterator;
}
}
Below is the linked list class (which i have also templated):
class List
{
private:
struct Node
{
T data;
Node* next;
Node* previous;
Node() : next(NULL), previous(NULL) {} //define our own default constuctor
Node(T data) : next(NULL), previous(NULL), data(data) {}
};
typedef struct Node* NodeRef;
NodeRef head;
NodeRef tail;
NodeRef iterator; //points to one node at a time
NodeRef current1;//temp
int size;
public:
void insert(T);Inserts a new element into the list in the position after the "iterator"
void scroll() {iterator = iterator->next;}
when i call the insert function, i run into problems. the scroll function works fine.
iterator->next = iterator is incorrect and creates a loop. Since the previous line is temp->previous = iterator, iterator->next should point back at temp. Once you've updated both links, you should have n->next->prev == n for any valid node in the list.
This is my class
class NumberList
{
private:
// Declare a structure for the list
struct ListNode
{
double value[10]; // The value in this node
struct ListNode *next; // To point to the next node
};
ListNode *head; // List head pointer
public:
// Constructor
NumberList()
{ head = nullptr; }
// Destructor
~NumberList();
// Linked list operations
void appendNode(double []);
void insertNode(double []);
void deleteNode(double []);
void displayList() const;
};
This is my append function and I can't get it to work -- i keep getting an error message.
void NumberList::appendNode(double num[])
{
ListNode *newNode; // To point to a new node
ListNode *nodePtr; // To move through the list
// Allocate a new node and store num there.
newNode = new ListNode;
newNode->value = num;
newNode->next = nullptr;
// If there are no nodes in the list
// make newNode the first node.
if (!head)
head = newNode;
else // Otherwise, insert newNode at end.
{
// Initialize nodePtr to head of list.
nodePtr = head;
// Find the last node in the list.
while (nodePtr->next)
nodePtr = nodePtr->next;
// Insert newNode as the last node.
nodePtr->next = newNode;
}
}
Error message:
prog.cpp: In member function ‘void NumberList::appendNode(double*)’: prog.cpp:40:19: error: incompatible types in assignment of ‘double*’ to ‘double [10]’ newNode->value = num;
Any suggestions about what i'm doing wrong?
The type of the parameter num in void NumberList::appendNode(double num[]) is really a pointer (= double*), rather than an array with a defined number of elements.
Using std::array<double,10> in your structure and as the parameter to appendNode would be a good solution.
This:
struct ListNode
{
double value[10];
...
Becomes:
struct ListNode
{
std::array<double,10> value;
...
And your function parameters would be declared as:
void appendNode(const std::array<double,10>& num);
newNode->value = num; requires no change.
I'm building my own linked list class and I'm having some issues figuring out how to write some functions to help me traverse this list. This is my first time building a linked list from scratch, so if my approach is unconventional please let me know what might be more conventional.
I'd like write a function, within the List class that allows me to increment to the next element called getNext() as well as one that getPrev();
I wrote getNext like this:
T* getNext(){return next;}
However it tells me next is not declared within the scope. I'd also like to write a function that lets me access and modify the object within the list. I was considering using the bracket operator, but first I need to write a function to return the data member. Perhaps If I take a similar approach as I did within my pop functions.. thinking about it now. However, I'd still appreciate any advice.
Here is my List class:
#ifndef LIST_H
#define LIST_H
//List Class
template <class T>
class List{
struct Node {
T data;
Node *next;
Node *prev;
//Constructs Node Element
Node(T t, Node* p, Node* n) { data = (t); prev = (p); next = (n); }
// T *getNext() {return next;}
};
Node *head;
Node *tail;
public:
//Constructor
List() { head = NULL; tail=NULL; }
//Destructor
~List() {
while(head){
Node * temp(head);
head = head->next;
delete temp;
}
}
//is empty
bool empty() const {return (!head || !tail ); }
operator bool() const {return !empty(); }
//Push back
void push_back(T data) {
tail = new Node(data, tail, NULL);
if(tail->prev) //if the node in front of tail is initilized
tail->prev->next = tail;
if( empty() )
head = tail;
}
//Push front
void push_front(T data) {
head = new Node(data, NULL, head);
if(head->next)//if the node following head is initilized
head->next->prev = head;
if( empty() )
tail = head;
};
T pop_back() {
if( empty() )
throw("Error in List: List is empty\n");
Node* temp(tail);
T data(tail->data);
tail = tail->prev;
if( tail )
tail->next = NULL;
else
head = NULL;
delete temp;
return data;
}
T pop_front() {
if (empty())
throw("Error in List: List is empty\n");
Node* temp(head);
T data(head->data);
head = head->next;
if(head)
head->prev=NULL;
else
tail = NULL;
delete temp;
return data;
}
T getNext(){return next;}
};
#endif
getNext should be part of the struct Node and return a Node*
Node* getNext() { return next; }
Then from that you can get the value.
If you have to have it part of the list itself, which I would not recommend it will need to take a parameter of what Node you would like the next of:
Node* getNext(Node* n) {return n->next;}
Again, I recommend the first option.
Here is an approximate whole class with both of these:
template<typename T>
class List {
public:
struct Node {
Node* next, prev;
T data;
//some constructor and stuff
Node* Next() {return next;}
}
//some constructors and other functions
Node* getNext(Node* _n) {return _n->Next();}
}
then to use:
int main() {
List<int> l;
//add some stuff to the list
//get the head of the list
List<int>::Node* head = l.head; //or some corresponding function
//then
List<int>::Node* next = head->Next();
//or
List<int>::Node* next2 = l.getNext(head);
}
for starters getNext() should not return a pointer to the template class, it should return a pointer to the Node structure.
So it should be
Node* getNext(){return next;}
Because it's a member of Node struct and getNext is member of List. You should access it from an object of type Node.
I'm creating a Linked List program and I currently have this method to insert an item into the front of the list:
template <class T>
void LinkedList<T>::insert(T *o)
{
node newNode;
newNode.o = o;
newNode.next = first;
newNode.prev = NULL;
first->prev = &newNode;
first = &newNode;
}
where I have a struct as follows:
struct node {
node *next;
node *prev;
T *o;
};
I think my logic is right for the insert method; however, I feel as if I'm not doing it properly, specifically dealing with the pointers. I feel as if I have to many newNode. lines and that I could do this better somehow. Any suggestions or is it right?
Note: I'm new to C++ so please be kind. I know this is a simple question
newNode is local to insert() and will be destructed when that method returns, meaning first->prev and first will be pointing to a node that no longer exists.
Use new:
template <class T>
void LinkedList<T>::insert(T *o)
{
node* newNode = new node;
newNode->o = o;
newNode->next = first;
newNode->prev = NULL;
first->prev = newNode;
first = newNode;
}
struct node {
int data;
struct node* next;
}
void push (struct node **head, int data) {
struct node* newNode = malloc (sizeof (struct node));
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
//I understand c version well.
C++ version
void Stack::push( void *data ) {
struct node *newNode = new node;
newNode->data = data;
newNode->next = head;
head = newNode;
}
In c++ head is a private or protected member of stack class and is declared as node *head.
Question: why head can preserve its value after push() call in c++.
In c, we need to declare it as ** since we want to change the value of head pointer after the push() function call. In c++ code, won’t changes to head be lost after the call?
The problem here is the C code you're comparing to C++ is not really analogous. A better example would be
typedef struct Node {
int data;
struct Node* pNext;
} Node;
typedef struct Stack {
Node* pHead;
} Stack;
void push(Stack* this, int data) {
Node* newNode = malloc (sizeof (Node));
newNode->data = data;
newNode->next = this->head;
this->head = newNode;
}
In this version we've successfully implemented push without having to take a ** for head. We have in a way because it's double indirected via the Stack*. But this is very similar to how C++ works. It's possible to view C++ as passing this as a hidden argument to the function.
In this case, since Stack::push is non-static, head is a shorthand for this->head. So the head = newNode is the same as:
this->head = newNode;