I'm writing a C++ programm which has to work with linked list. But I can't figure out how can I access structure which is in another structure.
#include <cstddef>
#include "list.hpp"
using std::size_t;
struct list {
struct node {
double val;
node* prev;
node* next;
};
node* head = nullptr;
node* tail = nullptr;
size_t size = 0;
};
Can you explain me how it works? I have a method, but I don't know how I can use this structur in this method.
void push_back(list& l, double elem) {
node *new_node = new node(elem);
if (l.head==null) {
l.head = new_node;
}
node *curent = l.head;
while (curent) {
if (!curent->next) {
curent->next = new_node;
}
cur = cur->next;
}
}
Thank you.
in this code , you have a doubly linked list
i'll try to explain the code of the push_back function .
at the beginning we have void push_back(list& l, double elem) , l is your current LinkedList whish you want to add a new element to it in queue, elem is the value of your new element .
if (l.head==null) {
l.head = new_node;
}
if your linkedList is empty , we add the new element
exemple1 : empty LinkedList
if the linkedList is not empty
push back
this a simple code
node *curent = l.head; // the current node is pointed to the head of the LinkedList
while (curent->next != null) { // while current->next is not equal to null
curent=curent->next ; // step forward to the next node
}
curent->next =new_node ; // add the new node to the queue of the linkedList
Related
I'm trying to delete a node in a singly linked list in a given position.When i submit this code all the test cases are success.But except one and the compiler shows abort called.When i googled it it shows resource exceeded.Is there is any other way to optimize this code to reduce the resource usage.
I have written my code inside SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* head, int position) function.
You’re given the pointer to the head node of a linked list and the position of a node to delete. Delete the node at the given position and return the head node. A position of 0 indicates head, a position of 1 indicates one node away from the head and so on. The list may become empty after you delete the node.
Input Format
You have to complete the deleteNode(SinglyLinkedListNode* llist, int position) method which takes two arguments - the head of the linked list and the position of the node to delete. You should NOT read any input from stdin/console. position will always be at least 0 and less than the number of the elements in the list.
The first line of input contains an integer
, denoting the number of elements in the linked list.
The next lines contain an integer each in a new line, denoting the elements of the linked list in the order.
The last line contains an integer
denoting the position of the node that has to be deleted form the linked list.
Constraints
, where is the element of the linked list.
Output Format
Delete the node at the given position and return the head of the updated linked list. Do NOT print anything to stdout/console.
The code in the editor will print the updated linked list in a single line separated by spaces.
#include <bits/stdc++.h>
using namespace std;
class SinglyLinkedListNode {
public:
int data;
SinglyLinkedListNode *next;
SinglyLinkedListNode(int node_data) {
this->data = node_data;
this->next = nullptr;
}
};
class SinglyLinkedList {
public:
SinglyLinkedListNode *head;
SinglyLinkedListNode *tail;
SinglyLinkedList() {
this->head = nullptr;
this->tail = nullptr;
}
void insert_node(int node_data) {
SinglyLinkedListNode* node = new SinglyLinkedListNode(node_data);
if (!this->head) {
this->head = node;
} else {
this->tail->next = node;
}
this->tail = node;
}
};
void print_singly_linked_list(SinglyLinkedListNode* node, string sep, ofstream& fout) {
while (node) {
fout << node->data;
node = node->next;
if (node) {
fout << sep;
}
}
}
void free_singly_linked_list(SinglyLinkedListNode* node) {
while (node) {
SinglyLinkedListNode* temp = node;
node = node->next;
free(temp);
}
}
// Complete the deleteNode function below.
/*
* For your reference:
*
* SinglyLinkedListNode {
* int data;
* SinglyLinkedListNode* next;
* };
*
*/
SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* head, int position) {
int i = 0;
SinglyLinkedListNode* temp = new SinglyLinkedListNode(2);
SinglyLinkedListNode* c;
SinglyLinkedListNode* p;
c = head;
p = head;
for(;i!=position;p=c,c=c->next,i++);
p->next = c->next;
delete c;
return head;
}
int main()
I modified the answer and found that deleteion at position 0 is the problem.Now it works fine.
SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* head, int position) {
SinglyLinkedListNode* p;
SinglyLinkedListNode* c;
p=head;
c=head;
if(position==0)
{
SinglyLinkedListNode *temp;
temp=head;
head = head->next;
delete temp;
return head;
}
int i = 0;
for(;i!=position;i++,p=c,c=c->next);
p->next = c->next;
delete c;
return head;
}
I still struggle with the recursion technique to solve the problem. I know there are nicer ways to solve my problem below of reversing a linked list. Most of the ways that I have seen, start to reverse the pointers by going from the head to the tail, either by using iteration or recursion.
I am trying for interest to reverse the list by first finding the last node in the list recursively and then changing the pointers everytime the function returns.
What am I doing wrong below exactly? Or will this method even work , without the need to pass more parameters to the recursive function? Thanks in advance for your help.
struct Node
{
int data;
struct Node *next;
};
Node* Reverse(Node *head)
{
static Node* firstNode = head;
// if no list return head
if (head == NULL)
{
return head;
}
Node* prev = NULL;
Node* cur = head;
// reached last node in the list, return head
if (cur->next == NULL)
{
head = cur;
return head;
}
prev = cur;
cur = cur->next;
Reverse(cur)->next = prev;
if (cur == firstNode)
{
cur->next = NULL;
return head;
}
return cur;
}
EDIT : Another attempt
Node* ReverseFromTail(Node* prev, Node* cur, Node** head);
Node* ReverseInit(Node** head)
{
Node* newHead = ReverseFromTail(*head, *head, head);
return newHead;
}
Node* ReverseFromTail(Node* prev, Node* cur, Node** head)
{
static int counter = 0;
counter++;
// If not a valid list, return head
if (head == NULL)
{
return *head;
}
// Reached end of list, start reversing pointers
if (cur->next == NULL)
{
*head = cur;
return cur;
}
Node* retNode = ReverseFromTail(cur, cur->next, head);
retNode->next = cur;
// Just to force termination of recursion when it should. Not a permanent solution
if (counter == 3)
{
cur->next = NULL;
return *head;
}
return retNode;
}
Finally Solved it :
Node* NewestReverseInit(Node* head)
{
// Invalid List, return
if (!head)
{
return head;
}
Node* headNode = NewestReverse(head, head, &head);
return headNode;
}
Node* NewestReverse(Node *cur, Node* prev, Node** head)
{
// reached last node in the list, set new head and return
if (cur->next == NULL)
{
*head = cur;
return cur;
}
NewestReverse(cur->next, cur, head)->next = cur;
// Returned to the first node where cur = prev from initial call
if (cur == prev)
{
cur->next = NULL;
return *head;
}
return cur;
}
I will not give you the code, I will give you the idea. You can implement the idea in the code.
The key to all recursion problems is to figure out two cases: repetition step and end case. Once you do this, it works almost as if magically.
Applying this principle to reversing a linked list:
End case: the list of one element is already reversed (this is straightforward) and returning the element itself
Repetition case: Given list L, reversing this least means reversing an L', where L' is the L' is the list without the very first element (usually called head), and than adding the head as the last element of the list. Return value would be the same as a return value of the recursive call you just made.
It can be done. The key in understanding recursion is What is the starting point?
Usually I create a "starting" function which prepares the first call. Sometimes it is a separate function (like in non OO implemnatation at bottom). Sometimes it's just a special first call (like in example below).
Also the key is in remembering variables before they change and what is the new head.
The new head is the last element of the list. So You have to get it up from the bottom of the list.
The nextelement is always your parent.
Then the trick is to do everything in the correct order.
Node* Reverse( Node* parent) // Member function of Node.
{
Node* new_head = next ? next->Reverse( this )
: this;
next = parent;
return new_head;
}
You call the function with: var.Reverse( nullptr);
Example:
int main()
{
Node d{ 4, nullptr };
Node c{ 3, &d };
Node b{ 2, &c };
Node a{ 1, &b };
Node* reversed = a.Reverse( nullptr );
}
So what is happening here?
First we create a linked list:
a->b->c->d->nullptr
Then the function calls:
a.Reverse(nullptr) is called.
This calls the Reverse on the next node b.Reverse with parent a.
This calls the Reverse on the next node c.Reverse with parent b.
This calls the Reverse on the next node d.Reverse with parent c.
d doesn't have next node so it says that the new head is itself.
d's next is now it's parent c
d returns itself as the new_head.
Back to c: new_head returned from d is d
c's next is now it's parent b
c returns the new_head it recieved from d
Back to b: new_head returned from c is d
b's next is now it's parent a
b returns the new_head it recieved from c
Back to a: new_head returned from b is d
a's next is now it's parent nullptr
a returns the new_head it recieved from b
d is returned
Non object oriented implementation;
Node* reverse_impl(Node* parent)
{
Node* curr = parent->next;
Node* next = curr->next;
Node* new_head = next ? reverse_impl( curr )
: curr;
curr->next = parent;
return new_head;
}
Node* reverse(Node* start)
{
if ( !start )
return nullptr;
Node* new_head = reverse_impl( start );
start->next = nullptr;
return new_head;
}
Here's a full implementation I wrote in 5 minutes:
#include <stdio.h>
struct Node
{
int data;
struct Node *next;
};
struct Node* Reverse(struct Node *n)
{
static struct Node *first = NULL;
if(first == NULL)
first = n;
// reached last node in the list
if (n->next == NULL)
return n;
Reverse(n->next)->next = n;
if(n == first)
{
n->next = NULL;
first = NULL;
}
return n;
}
void linked_list_walk(struct Node* n)
{
printf("%d", n->data);
if(n->next)
linked_list_walk(n->next);
else
printf("\n");
}
int main()
{
struct Node n[10];
int i;
for(i=0;i<10;i++)
{
n[i].data = i;
n[i].next = n + i + 1;
}
n[9].next = NULL;
linked_list_walk(n);
Reverse(n);
linked_list_walk(n+9);
}
Output:
0123456789
9876543210
So I have to create a linked list for class and I am stuck with my List::Current() function. For some reason I'm getting a handling error when I try to call the function.
List.h
class List {
private:
struct Node {
int data;
Node* next;
Node() : next(NULL){} //define our own default constructor
Node(int data) : next(NULL), data(data){}
};
typedef struct Node* NodeRef;
NodeRef head;
NodeRef tail;
NodeRef iterator; //points to one node at a time
int size;
public:
int current();
List.cpp
// initialize the values when they are instantiated
List::List() : head(NULL), tail(NULL), iterator(NULL), size(0)
{}
int List::current() {
return iterator->data;
}
void List::push_front(int data) //Inserting a new node in the front of the list
{
if (size == 0) //If there is no nodes in the list, execute the if statement
{
head = new Node(data); //create a new node, and have head point to it
iterator = tail = head; //have tail point to the new node also.
}
else //If there are nodes in the list, execute the else statement
{
NodeRef newNode = new Node(data); //create a new node
newNode->next = head; //have the next pointer point to the head of the next node.
head = newNode; //have the head pointer point to the new node inserted at the beginning of the list
}
size++; //Increment the size counter
}
void List::push_back(int data) //Inserting a node at the end of a list
{
if (size == 0) //If there are no nodes in the list, execute the if statement
{
tail = new Node(data); //Create a new node and have the tail pointer point to it.
iterator = head = tail; //Have the head pointer point to the new node also.
}
else //If there is atleast 1 node in the list, execute the else statement
{
NodeRef newNode = new Node(data); //Create a new node
tail->next = newNode; //Have the tail
tail = newNode; //Have the tail pointer point to the new node.
newNode->next = NULL;
}
size++;
}
void List::begin() //Set the iterator to the head of the list
{
iterator = head;
}
void List::scroll() //Allows us to scroll through the list
{
if (iterator == NULL)
cout << "Iterator is pointing to null" << endl;
else
iterator = iterator->next;
}
LinkedList.cpp
#include "stdafx.h"
#include "List.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {
List B; //Create a new list
B.push_front(5);
B.push_front(4);
B.push_front(3);
B.push_back(10);
cout << B.current() << endl;
system("PAUSE");
return 0;
}
I left some code out because I didn't think listing the other functions that worked properly were necessary to get the point across. If you would like everything I could post that.
I think this solved my issues.
Your issue is you aren't setting iterator.
Personally I wouldn't include it as part of the class and have something like begin() or head() which retrieves an iterator class instance with the head pointer. Then the current and iteration methods would be a part of your iteration class.
But for your current design you could check in push_front to see if the iterator is NULL, and if so set it equal to head. Or you could have a begin_iteration method which sets it to the head, which would also allow you to do more than one iteration through the list.
Edit
Now that you have revealed your entire implementation, you need to set iterator in 2 places. At the end of push_front, and if there is no head in push_back. In other words anywhere you set head, you need to set iterator.
Also how do you move iterator forward? Can you restart the iteration?
I'm trying to write an insert function for string values for a circular doubly linked list. I saw that creating a dummy node is beneficial in doing this so I can eliminate special cases like when the list is empty. The problem is I'm not finding alot of good information on dummy head nodes. I understand their purpose, but I don't understand how I create/implement it.
appreciate all the code examples guys, tried to figure it out on my own getting a little stuck though if someone can look at it.
#include <iostream>
#include <string>
using namespace std;
typedef string ListItemType;
struct node {
node * next;
node * prev;
ListItemType value;
};
node * head;
node * dummyHead = new node;
void insert(const ListItemType input, node * & within);
void main(){
insert("bob",dummyHead);
}
void insert( const ListItemType input, node * &ListHead){
node *newPtr = new node;
node *curr;
newPtr->value = input;
curr = ListHead->next; //point to first node;
while (curr != ListHead && input < curr->value){
curr = curr->next;
}
//insert the new node pointed to by the newPTr before
// the node pointed to by curr
newPtr->next = curr;
newPtr->prev = curr->prev;
curr->prev = newPtr;
newPtr->prev->next = newPtr;
}
For a circular doubly linked list, you can setup 1 sentinel node where both "next" and "prev" points to itself when list is empty. When list is not empty, sentinel->next points to first element and sentinel->prev points to last element. With this knowledge, your insert and remove function would look something like this.
This is very basic and your LinkedList and Node class maybe implemented differently. That is OK. The main thing is the insert() and remove() function implementation that shows how sentinel node(s) removes the need for checking for NULL values.
Hope this helps.
class DoublyLinkedList
{
Node *sentinel;
int size = 0;
public DoublyLinkedList() {
sentinel = new Node(null);
}
// Insert to the end of the list
public void insert(Node *node) {
// being the last node, point next to sentinel
node->next = sentinel;
// previous would be whatever sentinel->prev is pointing previously
node->prev = sentinel->prev;
// setup previous node->next to point to newly inserted node
node->prev->next = node;
// sentinel previous points to new current last node
sentinel->prev = node;
size++;
}
public Node* remove(int index) {
if(index<0 || index>=size) throw new NoSuchElementException();
Node *retval = sentinel->next;
while(index!=0) {
retval=retval->next;
index--;
}
retval->prev->next = retval->next;
retval->next->prev = retval->prev;
size--;
return retval;
}
}
class Node
{
friend class DoublyLinkedList;
string *value;
Node *next;
Node *prev;
public Node(string *value) {
this->value = value;
next = this;
prev = this;
}
public string* value() { return value; }
}
Why are you trying to use dummy node?
I hope you can handle it without a dummy node.
Eg:
void AddNode(Node node)
{
if(ptrHead == NULL)
{
ptrHead = node;
}else
{
Node* itr = ptrHead;
for(int i=1; i<listSize; i++)
{
itr = itr->next;
}
itr->next = node;
}
listSize++;
}
The above one is an example to handle the linked list without dummy node.
For a circular double linked list without a dummy node, the first node previous pointer points to the last node, and the last node next pointer points to the first node. The list itself has a head pointer to first node and optionally a tail pointer to last node and/or a count.
With a dummy node, the first node previous pointer points to the dummy node and the last node next pointer points to the dummy node. The dummy nodes pointers can point to the dummy node itself or be null.
The HP / Microsoft STL list function uses a dummy node as a list head node with the next pointer used as a head pointer to the first real node, and the previous pointer used as a tail pointer to the last real node.
#include <iostream>
#include <string>
using namespace std;
typedef string ElementType;
struct Node
{
Node(){}
Node(ElementType element, Node* prev = NULL, Node* next = NULL):element(element){}
ElementType element;
Node* prev;
Node* next;
};
class LinkList
{
public:
LinkList()
{
head = tail = dummyHead = new Node("Dummy Head", NULL, NULL);
dummyHead->next = dummyHead;
dummyHead->prev = dummyHead;
numberOfElement = 0;
}
void insert(ElementType element)
{
Node* temp = new Node(element, NULL, NULL);
if (0 == numberOfElement)
{
head = tail = temp;
head->prev = dummyHead;
dummyHead->next = head;
tail->next = dummyHead;
dummyHead->prev = tail;
}
else
{
tail->next = temp;
temp->prev = dummyHead->next;
temp->next = dummyHead;
dummyHead->next = temp;
tail = temp;
}
numberOfElement += 1;
}
int length() const { return numberOfElement; }
bool empty() const { return head == dummyHead; }
friend ostream& operator<< (ostream& out, const LinkList& List);
private:
Node* head;
Node* tail;
Node* dummyHead;
int numberOfElement;
};
ostream& operator<< (ostream& out, const LinkList& List)
{
Node* current = List.head;
while (current != List.dummyHead)
{
out<<current->element<<" ";
current = current->next;
}
out<<endl;
return out;
}
int main()
{
string arr[] = {"one", "two", "three", "four", "five"};
LinkList list;
int len = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < len; ++i)
{
list.insert(arr[i]);
}
cout<<list<<endl;
}
I think this code can help you. When you want to implement some data structure, you must have a clear blueprint about it.
Do the following inside the constructor
ptrHead = new Node();
listSize = 1;
if you have tail also,
ptrHead->next = ptrTail;
The above code will create dummy node.
Make sure you implementation should not affected by this dummy node.
eg:
int getSize()
{
return listSize-1;
}
#include <iostream>
using namespace std;
struct Node
{
int item; // storage for the node's item
Node* next; // pointer to the next node
};
Node* addNode(Node*& head, int data , int& count)
{
Node * q; // new node
q = new Node; // allocate memory for the new mode
q->item = data; // inserting data for the new node
q->next = head; // point to previous node ?? how would i do that? ( am i doing it correctly?)
count++; // keep track of number of node
head = q;
return q;
}
int main()
{
int a, count=0;
int data;
bool repeat;
Node *head= NULL;
//^^ assuming thats creating the first node ^^
do
{
cout << "please enter the data for the next node" <<endl;
cin >> data;
addNode(head, data, count);
cout << "do you wish to enter another node? (enter true or false)" << endl;
cin >>repeat;
}
while (repeat == true);
// assuming this is the print function
while(head != NULL)
{
cout << "output" << temp->item << endl;
cout << temp->next << endl;
}
system("pause");
return 0;
}
okey i tried adding a new element in the list how would i move the head around like a LIFO memory (stack) so the last element is on the very top..
any help would be appreciated ! The pointers and the nodes are messing with my brain lately ....
temp is an uninitialized pointer. So -
temp-> item = a; // temp is not initialized or pointing to a memory location
// that has Node object to use operator ->
First, temp needs to be allocated memory location using new.
temp = new Node;
temp -> item = a;
And now assign it head. Similarly allocate memory for the child nodes too in the while loop. And return all the resources acquired from child to head using delete before program termination.
You seem to have some misunderstandings here:
Your "head" is the start of the list. It's always the start.
You add append elements to a linked list by assigning them to the last node's next pointer.
Third, you're not allocating anything.
Node *head= new Node();
Node *temp = new Node();
cout<<"enter something into data"<<endl;
cin >> a ;
temp->item = a;
head->next = temp;
Now ... to add the next thing, you either need to keep track of the last node (tail), or traverse the list to find the last node.
Node *nextNode = new Node();
nextNode->item = 0.0;
Node *i;
for (i = head; i->next != null; i = i->next);
i->next = nextNode;
This is O(n) execution time. By keeping track of the tail you make it O(1):
Node *head= new Node();
Node *tail = head;
Node *temp = new Node();
cout<<"enter something into data"<<endl;
cin >> a ;
temp->item = a;
tail->next = temp;
tail = temp;
Node *nextNode = new Node();
nextNode->item = 0.0;
tail->next = nextNode;
tail = nextNode;
EDIT: As pointed out, if you want to prepend to the list, you would:
temp->next = head;
head = temp;
Since I'm not sure every answer completely answers it, here's a linked list implementation (written without testig:
// your (correct) structure
struct Node
{
float item; // storage for the node's item
Node* next; // pointer to the next node
};
Now we need two pointers somewhere to look after the list:
/* some pointers */
struct List
{
Node* head;
Node* tail;
};
Now we need to create some elements. As others have said, you can do that with new:
/* create some elements we want to link in */
Node* elem1 = new Node();
Node* elem2 = new Node();
Node* elem3 = new Node();
/* maybe even set their properties! */
elem1->item = 3.14;
elem2->item = 3.14;
elem3->item = 3.14;
Notice how I didn't try to add these elements to a list yet? That's because I've got a function in mind which looks like this:
void addtolist(List &list, Node* node)
{
/* if no head, initialise the list */
if ( list->head == NULL )
{
list->head = node;
list->tail = node;
}
else if ( list->head != NULL && list->tail != NULL )
{
/* access the tail element and set its
next to this ptr.
Move tail to this node */
list->tail->next = node;
list->tail = node;
}
else
{
/* probably raise an exception! */
}
}
You can call this by doing this:
List l;
addtolist(l, elem1); /* etc */
Deleting elements is somewhat more tricky, since you have to go to that element, remember its previous element, grab it's next element, join them up and delete the Node* you're on.
Now for traversing lists... your terminology HEAD|TAIL reminds me of Erlang and tail recursion, where the current element is referred to as the head and the remainder the tail. If I write:
Node* cur = l.head;
while ( cur != NULL )
{
// do something with cur.item ?
cur = cur->next;
}
You can see this happening. Replacing cur with head here would be harmless thanks to the List struct.
Finally, I've used a very C-like approach here, but there's scope for templates:
template<typename T>
struct node
{
T item; // storage for the node's item
Node<T>* next; // pointer to the next node
};
and encapsulating the List struct as a class:
template<typename T>
class List
{
protected:
Node<T>* head;
Node<T>* tail;
public:
void addtolist(Node<T>* node);
Node<T>* gethead();
Node<T>* gettail();
}
Which brings you a little bit closer to std::list.
Additionally note that you are doing an implicit cast from int to float on
temp-> item = a;
as a is an int, while temp->item is a double.
To solve your problem: You want to allocate a new structure before accessing temp, thus
temp = new Node();