Reputation: 93
I'm trying to implement my own list class but am having trouble reversing just part of my list.
Revelant code:
void List<T>::reverse(ListNode * & head, ListNode * & tail)
{
ListNode* t;
ListNode* curr = head;
ListNode * funtail = tail;
int stop=0;
while(stop==0)
{
if(curr==funtail)
{
stop = 1;
}
t = curr->prev;
curr->prev = curr->next;
curr->next = t;
curr = curr->prev;
}
t = tail;
tail = head;
head = t;
}
If I start with the list
1 2 3 4 5 6 7 8 9 10
and I pass in pointers to 1 and 4, then the list should look like
4 3 2 1 5 6 7 8 9 10
The problem is, my list returns as just
1
with the rest of the list lost (well, still accessible from my global tail variable). Any ideas? Is my method wrong?
Upvotes: 1
Views: 3281
Reputation: 469
A simpler solution.
/**
* Traverses half of the list and swaps a node with another node(
here by termed as the reflection node)
* which lies at a position = listSize - (i +1) for every i.
* Reassignment of element is not needed, hence a soul saver from
* the copy constructor thing ( '=' assignment operator stuff).
*/
template <typename E> void DLinkedList<E>::reverse(){
int median = 0;
int listSize = size();
int counter = 0;
if(listSize == 1)
return;
/**
* A temporary node for swapping a node and its reflection node
*/
DNode<E>* tempNode = new DNode<E>();
for(int i = 0; i < listSize/2 ; i++){
DNode<E>* curNode = nodeAtPos(i);
// A node at 'i'th position
DNode<E>* reflectionNode = nodeAtPos(listSize - (i + 1));
// Reflection of a node considering the same distance from the median
/**
* swap the connections from previous and next nodes for current and
* reflection nodes
*/
curNode->prev->next = curNode->next->prev = reflectionNode;
reflectionNode->prev->next = reflectionNode->next->prev = curNode;
/**
* swapping of the nodes
*/
tempNode->prev = curNode->prev;
tempNode->next = curNode->next;
curNode->next = reflectionNode->next;
curNode->prev = reflectionNode->prev;
reflectionNode->prev = tempNode->prev;
reflectionNode->next = tempNode->next;
}
delete tempNode;
}
template <typename E> int DLinkedList<E>::size(){
int count = 0;
DNode<E>* iterator = head;
while(iterator->next != tail){
count++;
iterator = iterator->next;
}
return count;
}
template <typename E> DNode<E>* DLinkedList<E>::nodeAtPos(int pos){
DNode<E>* iterator = head->next;
int listSize = size();
int counter = 0;
while(counter < pos){
iterator = iterator->next;
counter++;
}
return iterator;
}
Upvotes: 0
Reputation: 4328
Your head->prev
must be pointing to NULL
in first for loop . You better think and implement digramatically it will be helpful . You need t->next->next =t->next
.
Upvotes: 0
Reputation: 3564
If you reverse the segment [first,last], you want first->next
set to last->next
, not to first->prev
, as your code does.
Upvotes: 2
Reputation: 485
The problem happens for the first node, since Node 1 prev pointer is NULL and you are assigning it to Node 1's next. You should assign 1's next to Node 5
Upvotes: 0
Reputation: 1218
In your method parameters you are mixing "Pointers" with "References".
void List::reverse(ListNode * & head, ListNode * & tail)
Maybe you mean?
void List::reverse(ListNode* head, ListNode* tail)
Upvotes: -1