I\'m having some trouble create a linkedlist in reverse order from a given linkedlist.
I come from a java background, and just started doing some C++.
Can yo
Node* revHead;
// ...
while(current != NULL)
{
//check if it's the first one being added
if(revHead == NULL)
You don't initialize revHead but you use it.
(I hope it is already clear to you that revHead is a local variable used to store a memory address, and not something that exists outside the method/procedure)
The Storage Class of revHead is automatic (aka in the local scope-body). In C++ when you do a declaration like that, there is not guarantee that the value will be 0.
(unless the storage class is of type static or the variable is global where it is automatically initialized to 0 if no other value is provided. In your case the variable has storage class of type auto which means it is locally defined in a function, and when declaring a local variable, without specifying a value, the value is garbage. Keep in mind that with the next C++ Standard C++0x the keyword auto has a new meaning).
The value in your case is garbage which makes the if fail. See more Information here : Link
Do a
Node* revHead = NULL;
Keep in mind that maybe you may have errors like that in other part of your code as well.
The sample below use the recursion for reversing a linklist. I asked this Qs at a job interview. This has been tested and works. ListElem is the node.
void LinkList::reverse()
{
if(pFirst == NULL) return;
ListElem* current = pFirst;
revCur(NULL, current, NULL);
}
void LinkList::revCur(ListElem *prev, ListElem* current, ListElem* next)
{
// ListElem *prev = NULL, *current = NULL, *next = NULL;
if ( current != NULL )
{
next = current->next;
current->next = prev;
prev = current;
current = next;
pFirst = prev;
this->revCur(prev,current,next);
}
}
Another method would be to first traverse the list and store all data in a stack,then create a new list and insert data in it from top of the stack.Stack being LIFO will give you the data in reverse order and hence you will have a reversed list.
My fully executable solution for a reversed linked list using a class since most examples one finds are using just a struct:
#include <iostream>
#include <string>
class listElement
{
std::string data;
listElement* next;
listElement* last; //for doubly linked list
void append(std::string);
void displayElements();
void reverseDisplayElements(listElement*);
listElement* reverseList(listElement*);
public:
listElement() = default;
listElement(std::string newElement)
:data(newElement)
, next(nullptr)
, last(this)
{}
listElement &operator=(const listElement& other) = default;
~listElement();
void setElement(std::string element){append(element);}
void getElements();
void getElementsReverse(listElement* elements);
listElement* setElementsInReverseOrder(listElement* elements);
};
listElement::~listElement()
{
//If the end is not reached, call the method again
if (next != nullptr)
{
next->~listElement();
delete(next);
}
}
void listElement::getElements()
{
std::cout << "\nPrint list:" << std::endl;
displayElements();
}
void listElement::getElementsReverse(listElement *elements)
{
std::cout << "\nJust print the list in reverse order:" << std::endl;
reverseDisplayElements(elements);
}
listElement *listElement::setElementsInReverseOrder(listElement *elements)
{
std::cout << "\n...Reversing elements..." << std::endl;
return reverseList(elements);
}
void listElement::append(std::string newData)
{
// Double linked list
// last->next = new listElement();
// last->next->data = newData;
// last->next->next = nullptr;
// last = last->next;
// Singly linked list
//has next the value nullptr?
//If yes, next pointer
if (next == nullptr)
{
next = new listElement();
next->data = newData;
next->next = nullptr;
}
//else the method again
else
next->append(newData);
}
listElement* listElement::reverseList(listElement* head)
{
//return if no element in list
if(head == nullptr)
return nullptr;
//initialize temp
listElement* temp{};
while(head != nullptr){
listElement* next = head->next;
head->next = temp;
temp = head;
head = next;
}
return temp;
}
void listElement::displayElements()
{
//cout the first entry
std::cout << data << std::endl;
//if the end is not reached, call method next again
if (next != nullptr)
next->displayElements();
}
void listElement::reverseDisplayElements(listElement*head)
{
//recursiv from the last to the list beginning - stop
listElement *temp = head;
if(temp != nullptr)
{
if(temp->next != nullptr)
{
reverseDisplayElements(temp->next);
}
std::cout << temp->data << std::endl;
}
}
int main ()
{
//Pointer to the Beginning of the list
listElement* linkedList = new listElement("Element 1");
//add more elements
linkedList->setElement("Element 2");
linkedList->setElement("Element 3");
linkedList->setElement("Element 4");
linkedList->getElements();
linkedList->getElementsReverse(linkedList);
linkedList->getElements();
linkedList = linkedList->setElementsInReverseOrder(linkedList);
linkedList->getElements();
return 0;
}
My recommendation for production code is using
the std::list since it is a linked list
or a std::vector if you need an efficient array implementation.
Easier one: Go through your linked list, save the previous and the next node and just let the current node point at the previous one:
void LinkedList::reversedLinkedList()
{
if(head == NULL) return;
Node *prev = NULL, *current = NULL, *next = NULL;
current = head;
while(current != NULL){
next = current->next;
current->next = prev;
prev = current;
current = next;
}
// now let the head point at the last node (prev)
head = prev;
}
This is done using just two temporary variables.
Node* list::rev(Node *first)
{
Node *a = first, *b = first->next;
while(a->next!=NULL)
{
b = a->next;
a->next = a->next->next;
b->next = first;
first = b;
}
return first;
}
Also, you can do this using recursion.