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.