Reputation: 738
i am trying to make a function that changes the order of the pointers of the nodes so that the original list is reversed.
my solution is based on iterating over the main list, then reversing the order of each 2 adjacent nodes: (n1)->(n2)
would be (n1)<-(n2)
after the first iteration.
my try:
Node push1(Node* curr) {
if(curr == NULL || *curr == NULL) {
return NULL;
}
Node temp = (*curr)->next;
if(temp == NULL) {
return NULL;
}
(*curr)->next = *curr;
return temp;
}
/*******************************/
void reverse2(Node* head) {
Node curr = *head;
while(curr != NULL) {
curr = push1(&curr);
}
}
PROBLEM: i ran through an infinity loop. i tried to fix that but then the list didn't reverse order. is there a way using this approach of push1()
that could work?
NOTE: i am not seeking the solution with 3 pointers or recursion.
Upvotes: 0
Views: 251
Reputation: 2828
This is fairly easy using a std::stack<> data structure in combination with a std::vector<>. Recall that Stacks are a type of container, designed to operate in a LIFO context (last-in first-out), where the elements are inserted and extracted only from one end of the container.
So in your situation you will create a stack, add your nodes to the stack in the order you already have, then popping them back off the stack reverses the order of the nodes.
I have sketched the code to do this but note that it is not tested, you should be able to adapt this idea to you situation:
#include <stack>
#include <vector>
std::vector<Node> reverseNodes(Node* currNode, Node* startNode) {
std::vector<Node> reversed;
std::stack<Node> nodeStack;
// First add nodes to the stack:
for (Node* aNode = currNode; aNode != startNode; aNode = aNode->next) {
nodeStack.push(aNode);
}
// Next add your starting node to the stack (last-in):
nodeStack.push(startNode);
// Popping off of the stack reverses the order:
while (!nodeStack.empty()) {
reversed.push_back(nodeStack.pop());
}
// Return the nodes ordered from last->first:
return reversed;
}
Upvotes: 1
Reputation: 1294
This is not readable or portable but it does not use recursion or additional variables:
struct list {
list *next;
/* ... */
};
list *
reverse(list *l)
{
list *head = nullptr;
while (l) {
head = (list *) ((uint64_t) head ^ (uint64_t) l->next);
l->next = (list *) ((uint64_t) l->next ^ (uint64_t) head);
head = (list *) ((uint64_t) head ^ (uint64_t) l->next);
l = (list *) ((uint64_t) l ^ (uint64_t) head);
head = (list *) ((uint64_t) head ^ (uint64_t) l);
l = (list *) ((uint64_t) l ^ (uint64_t) head);
}
return head;
}
The trick is to use xor
swaps.
Upvotes: 1
Reputation: 7687
This works, but is a bit silly
Node* push1(Node** prev, Node* curr)
{
Node* ret = curr->next;
curr->next = *prev;
(*prev)=curr;
return ret;
}
void reverse2(Node** head)
{
Node* prev = *head;
if(!prev) return;
Node* curr = prev->next;
if(!curr) return;
prev->next = 0;
while(curr)
{
curr = push1(&prev,curr);
}
*head = prev;
}
Upvotes: 1