This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
debug help - swap 2 nodes of double link list
I'm trying to write an algorithm that can swap two nodes in a singly linkedlist in C++. Here's what i have so far:
void swap(ListNode *node1, ListNode *node2)
{
ListNode *prev1 = head;
ListNode *prev2 = head;
//Search previous node for node1:
while(prev1->next!=node1 || prev1 != node1)
prev1 = prev1->getNext();
//Search previous node for node2:
while(prev2->next!=node2 || prev2 != node2)
prev2 = prev2->getNext();
if(node1->next==node2)
{ //This means node1 == prev2?
tail = node1;
node1->next = NULL;
head = node2;
node2->next = node1;
}
else if(node2->next==node1)
{ // node2 == prev1
tail = node2;
node2->next = NULL;
head = node1;
node1->next = node2;
}
if(node1->next == NULL)
{ //node1 is last
node1->next = node2->next;
tail = node2;
node2->next = NULL;
prev1->next = node2;
prev2->next = node1;
}
}
But I realized the number of different cases I can get, like if there LL was only two elements, or if they gave us node 2 before node 1, etc etc. I realized it can't be this complicated and ugly. So how do you write an algorithm to swap two nodes?
Doing the whole task in one routine is wrong. Break it down into two simpler problems:
1) Remove a node from a list, including all special cases.
2) Insert a node in a list, including all special cases.
From there, the overall problem is easy, but since this is obviously homework, you're on your own.
This seems cleaner to me:
//Maybe this function should go instide ListNode itself...
ListNode *prev(ListNode *node) {
if (node == head)
return null;
ListNode *search = head;
while (search != node)
search = search->getNext();
return search;
}
void swap(ListNode *node1, ListNode *node2)
{
ListNode *prev1 = prev(node1),
*prev2 = prev(node2),
*next1 = node1->getNext(),
*next2 = node2->getNext();
if (prev1)
prev1->next = node2;
else
head = node2;
if (prev2)
prev2->next = node1;
else
head = node1;
if (!next1)
tail = node2;
else if (!next2)
tail = node1;
node1->next = next2;
node2->next = next1;
}
Haven't tested this ofc...
#include <stdio.h>
struct llist {
struct llist *next;
char *payload;
} llists[]=
{{ llists+1, "one"}
,{ llists+2, "two"}
,{ llists+3, "three"}
,{ llists+4, "four"}
,{ llists+5, "five"}
,{ llists+6, "six"}
,{ llists+7, "seven"}
,{ llists+8, "eight"}
,{ llists+9, "nine"}
,{ NULL, "ten"}
};
struct llist *head = llists;
void llistswap(struct llist *one, struct llist * two)
{
struct llist **hnd, **h1, **h2;
h1 = h2 = NULL;
for (hnd= &head; *hnd; hnd = &(*hnd)->next) {
struct llist *tmp;
if ((*hnd) == one) h1 = hnd;
else if ((*hnd) == two) h2 = hnd;
else continue;
if (!h1 || !h2) continue;
tmp = *h1;
*h1 = *h2;
*h2 = tmp;
tmp = (*h1)->next;
(*h1)->next = (*h2)->next;
(*h2)->next = tmp;
break;
}
}
void do_print(struct llist *lp)
{
for ( ; lp; lp = lp->next) {
printf("%s%c", lp->payload, (lp->next) ?',' : '\n' );
}
}
int main(void)
{
do_print (head);
llistswap ( llists+4, llists+7);
do_print (head);
return 0;
}
Related
I have written a simple reverse function for the linked list, shown below:
typedef struct _NODE
{
int data;
_NODE *next;
}NODE;
void print(NODE *head)
{
NODE *start;
start = head;
while (start)
{
printf("%d ", start->data);
start = start->next;
}
}
NODE* reverse(NODE *head)
{
NODE *prev = NULL;
NODE *curr = head;
while (curr)
{
NODE *temp = curr->next;
curr->next = prev;
prev = curr;
curr = temp;
}
head = prev;
return head;
}
int main()
{
NODE *head = new NODE;
NODE *node1 = new NODE;
NODE *node2 = new NODE;
head->data = 1;
node1->data = 2;
node2->data = 3;
head->next = node1;
node1->next = node2;
node2->next = NULL;
reverse(head);
print(head);
getchar();
delete head;
delete node1;
delete node2;
head = NULL;
node1 = NULL;
node2 = NULL;
return 1;
}
I found the output will always be 1. My question is why does the head pointer after the reverse function always point to the node with value 1. I have already assigned the previous pointer to the head pointer in the reverse function.
But if I change below, the output became correct.
reverse(head);
To
head = reverse(head);
Because the head variable in the reverse function is not the same variable as the head variable in the main function.
Assigning to the head variable in reverse does not change the value of the head variable in main.
The void reve(struct Node *head) and display(struct Node *head) methods take one argument - the head of the linked list. I want to print the whole linked list but my display function print only 4.
#include <iostream>
using namespace std;
struct Node {
int data;
struct Node *link;
};
void display(struct Node *head) {
if (head == NULL) {
return;
}
cout << head->data << "\t";
display(head->link);
//head = head->link;
}
struct Node *reve(struct Node *head) {
struct Node *p = head;
if (p->link == NULL) {
head = p;
return head;
}
reve(p->link);
struct Node *temp = p->link;
temp->link = p;
p->link = NULL;
}
struct Node *insert(struct Node *head, int new_data) {
Node *new_node = new Node();
new_node->data = new_data;
new_node->link = head;
head = new_node;
return head;
}
int main() {
Node *head = NULL;
head = insert(head, 1);
head = insert(head, 2);
head = insert(head, 3);
head = insert(head, 4);
cout << "The linked list is: ";
//display(head);
head = reve(head);
display(head);
return 0;
}
Output
If you want the recursive way:
Node* reverse(Node* head)
{
if (head == NULL || head->next == NULL)
return head;
/* reverse the rest list and put
the first element at the end */
Node* rest = reverse(head->next);
head->next->next = head;
head->next = NULL;
/* fix the head pointer */
return rest;
}
/* Function to print linked list */
void print()
{
struct Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
The function reve does not return a value if p->link is not NULL.
Since head has more than 1 element, head = reve(head); has undefined behavior.
Reversing a linked list is much easier to implemented in a simple loop than with recursion:
struct Node *reve(struct Node *p) {
if (p != NULL) {
struct Node *prev = NULL;
while (p->link) {
struct Node *next = p->link;
p->link = prev;
prev = p;
p = next;
}
}
return p;
}
If your task requires recursion, you can make a extract the first node, reverse the remainder of the list and append the first node. Beware that this is not tail recursion, hence any sufficiently long list may cause a stack overflow.
struct Node *reve(struct Node *head) {
if (head != NULL && head->link != NULL) {
struct Node *first = head;
struct Node *second = head->link;
head = reve(second);
first->link = NULL; // unlink the first node
second->link = first; // append the first node
}
return head;
}
In C++ you need not to use keywords struct or class when an already declared structure or a class is used as a type specifier.
The function reve has undefined behavior.
First of all head can be equal to nullptr. In this case this statement
if (p->link == NULL) {
invokes undefined behavior.
Secondly the function returns nothing in the case when p->link is not equal to nullptr.
//...
reve(p->link);
struct Node *temp = p->link;
temp->link = p;
p->link = NULL;
}
Here is a demonstrative program that shows how the functions can be implemented. I used your C approach of including keyword struct when the structure is used as a type specifier.
#include <iostream>
struct Node
{
int data;
struct Node *link;
};
struct Node * insert( struct Node *head, int data )
{
return head = new Node{ data, head };
}
struct Node * reverse( struct Node *head )
{
if ( head && head->link )
{
struct Node *tail = head;
head = reverse( head->link );
tail->link->link = tail;
tail->link = nullptr;
}
return head;
}
std::ostream & display( struct Node *head, std::ostream &os = std::cout )
{
if ( head )
{
os << head->data;
if ( head->link )
{
os << '\t';
display( head->link, os );
}
}
return os;
}
int main()
{
struct Node *head = nullptr;
const int N = 10;
for ( int i = 0; i < N; i++ )
{
head = insert( head, i );
}
display( head ) << '\n';
head = reverse( head );
display( head ) << '\n';
return 0;
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
display is fine.
First thing I have notices is that you are trying to modify a copied value. For example, line 16. This code has no effect.
Note that you have a bug on insert: You return head instead of new_node.
Your version fails for lists with more than 1 item. reve() is supposed to return the last node of the original list, which you do not, hence lastNode would not point to the last node of the reversed list. So my advice is that you keep it aside.
So, reve:
struct Node* reve(struct Node* head) {
if (head->link == NULL) {
return head;
}
struct Node* lastNode = reve(head->link);
lastNode->link = head;
head->link = NULL;
return head;
}
and main:
int main() {
Node* head = NULL;
Node* last_node = head = insert(head, 1);
head = insert(head, 2);
head = insert(head, 3);
head = insert(head, 4);
head = reve(head);
cout << "The linked list is: ";
// Now, last_node is the new head
display(last_node);
return 0;
}
I have the following linked list:
2->1->9->8->3->1->nullptr.
I want to partition the linked list around the value 4, such that all values less than 4, come before all values greater than or equal to 4.
I can partition the linked list using a single function. But, I want to do it using two function - a function lesserThan(head,x) and a function greaterThan(head, x) - where x is the value around which I want to partition the list.
But, I am running into the following problem: If I use both functions together, the list nodes are modified by the first function - and, the second function works on that modified nodes. The functions work fine, when the other one is commented out. That is, lesserThan(head,x) works fine, when greaterThan(head, x) is commented out, and vice-versa.
How can I partition the linked list, by still using both the functions in main()? The main problem I am having is that the nodes are getting modified in both lesserThan and greaterThan functions, and that is getting reflected in main().
Following is the code:
struct Node
{
int data;
Node* next;
};
Node* newNode(int data)
{
Node* temp = new Node;
temp->data = data;
temp->next = nullptr;
return temp;
}
Node* lesserThan(Node* head, int x)
{
if (head == nullptr)
{
return nullptr;
}
Node* list1=nullptr, *temp1 = nullptr;
if ((head)->data < x)
{
temp1=list1 = head;
}
else
{
while (head && head->data >= x)
{
head = head->next;
}
if (head && head->data < x)
{
temp1 = list1 = head;
}
}
Node* curr = temp1;
if(curr)
curr = curr->next;
while (curr)
{
Node* next = curr->next;
if (curr->data<x)
{
list1->next = curr;
list1 = curr;
list1->next = nullptr;
}
curr = next;
}
return temp1;
}
Node* greaterThan(Node* head, int x)
{
Node* temp2 = nullptr, *list2=nullptr;
if (head->data >= x)
{
temp2 =list2= head;
}
else
{
while (head && head->data < x)
{
head = head->next;
}
if (head && head->data >= x)
{
temp2 = list2 = head;
}
}
Node* curr = list2;
if (curr)
curr = curr->next;
while (curr)
{
Node* next = curr->next;
if (curr->data >= x)
{
list2->next = curr;
list2 = curr;
list2->next = nullptr;
}
curr = next;
}
return temp2;
}
int main()
{
Node* head = newNode(2);
head->next = newNode(1);
head->next->next = newNode(9);
head->next->next->next = newNode(8);
head->next->next->next->next = newNode(3);
head->next->next->next->next->next = newNode(1);
int x = 4;
Node* p1 = lesserThan(head,x);
Node* p2 = greaterThan(head, x);
if (p1 != nullptr)
p1->next = p2;
while (p1)
{
cout << p1->data << " ";
p1 = p1->next;
}
cout << endl;
return 0;
}
Following are the two functions, that fail to work together, because the List nodes are modified by the first function (and second function), and that is reflected in main() -
How can I have the two functions in main, so that they don't effect each other? I tried creating different variables for head, and passing them to the functions. But that didn't work. Thanks for the help!
It will be better to use insert recursive function instead of your style and note that you have undeleted allocated nodes. I didn't consider them. Any way, I think the following code works as intented
struct Node
{
Node() = default;
Node( int dataVal ):data{dataVal}{}
int data{};
Node* next{};
};
Node*& lessThan( Node* const & head, int x){
if( !head ) throw std::invalid_argument("Empty linked list");
Node* toBeReturned;
Node* currentHeadNode = head;
Node** currentReturned = & toBeReturned;
while( currentHeadNode ){
if(currentHeadNode -> data < x ){
*currentReturned = new Node{ currentHeadNode -> data };
currentReturned = &((*currentReturned) -> next);
}
currentHeadNode = currentHeadNode->next;
}
return toBeReturned;
}
int main()
{
Node* head = new Node(2);
head->next = new Node(1);
head->next->next = new Node(9);
head->next->next->next = new Node(8);
head->next->next->next->next = new Node(3);
head->next->next->next->next->next = new Node(1);
int x = 4;
Node* p1 = lessThan(head,x);
while (p1)
{
std::cout << p1->data << " ";
p1 = p1->next;
}
std::cout << std::endl;
return 0;
}
I have been struggling for hours on end with this problem. My goal is to sort a linked list using only pointers (I cannot place linked list into vec or array and then sort). I am given the pointer to the head node of the list. The only methods i can call on the pointers are head->next (next node) and head->key (value of int stored in node, used to make comparisons). I have been using my whiteboard excessively and have tried just about everything I can think of.
Node* sort_list(Node* head)
{
Node* tempNode = NULL;
Node* tempHead = head;
Node* tempNext = head->next;
while(tempNext!=NULL) {
if(tempHead->key > tempNext->key) {
tempNode = tempHead;
tempHead = tempNext;
tempNode->next = tempNode->next->next;
tempHead->next = tempNode;
tempNext = tempHead->next;
print_list(tempHead);
}
else {
tempHead = tempHead->next;
tempNext = tempNext->next;
}
}
return head;
}
Since it's a singly linked list, we can do: (psuedo code)
bool unsorted = true;
while(unsorted) {
unsorted = false;
cur = head;
while(cur != nullptr) {
next = cur->next;
if(next < cur) {
swap(cur, next)
unsorted = true;
}
cur = cur->next;
}
}
I know its late but I also search for it but didn't get one so I make my own. maybe it will help someone.
I am using bubble sort (kind of sort algorithm) to sort data in a single linked list. It just swapping the data inside a node.
void sorting(){
Node* cur1 = head;
Node* cur2 = head;
for (int i = 0; i < getSize(); i++) {
for (int j = 0; j < getSize() - 1; j++) {
if (cur1->data < cur2->data) {
int temp = cur1->data;
cur1->data = cur2->data;
cur2->data = temp;
}
cur2 = cur2->next;
}
cur2 = head;
cur1 = head->next;
for (int k = 0; k < i; k++) {
cur1 = cur1->next;
}
}
}
Don't feel bad this is a lot harder than it sounds. If this were in an array it would be considerably easier. If the list were doubly linked it would be easier. Take a look at this code, it implements an insertion sort
struct Node {
int key;
Node *next;
} *NodePtr;
// do a simple selection sort http://en.wikipedia.org/wiki/Selection_sort
Node* sort_list(Node* head) {
Node *top = nullptr; // first Node we will return this value
Node *current = nullptr;
bool sorted = false;
while (sorted == false) {
// we are going to look for the lowest value in the list
Node *parent = head;
Node *lowparent = head; // we need this because list is only linked forward
Node *low = head; // this will end up with the lowest Node
sorted = true;
do {
// find the lowest valued key
Node* next = parent->next;
if (parent->key > next->key) {
lowparent = parent;
low = next;
sorted = false;
}
parent = parent->next;
} while (parent->next != nullptr);
if (current != nullptr) { // first time current == nullptr
current->next = low;
}
// remove the lowest item from the list and reconnect the list
// basically you are forming two lists, one with the sorted Nodes
// and one with the remaining unsorted Nodes
current = low;
if (current == head) { head = current->next; }
lowparent->next = low->next;
current->next = nullptr;
if (top == nullptr) {
top = current;
}
};
current->next = head;
return top;
}
int _tmain(int argc, _TCHAR* argv []) {
Node nodes[4];
nodes[0].key = 3;
nodes[1].key = 4;
nodes[2].key = 5;
nodes[3].key = 1;
nodes[0].next = &nodes[1];
nodes[1].next = &nodes[2];
nodes[2].next = &nodes[3];
nodes[3].next = nullptr;
auto sortedNodes = sort_list(&nodes[0]);
return 0;
}
Use a recursive approach as it is the easiest way of dealing with linked structures:
Pseudocode:
SORT(head)
if (head->next == null)
return
tempNode = head->next
SORT(tempNode)
if (tempNode->value < head->value)
SWAP(head, tempNode)
SORT(head)
return
so the let's say you have 5 4 3 2 1
1) 5 4 3 1 2
2) 5 4 1 3 2
3) 5 4 1 2 3
4) 5 1 4 2 3
5) 5 1 2 4 3
...
n) 1 2 3 4 5
Assume the Node like this:
struct Node
{
Node *next;
int key;
Node(int x) : key(x), next(NULL) {}
};
use insertion sort algorithm to sort the List:
Node* sort_list(Node* head)
{
Node dumy_node(0);
Node *cur_node = head;
while (cur_node)
{
Node *insert_cur_pos = dumy_node.next;
Node *insert_pre_pos = NULL;
while (insert_cur_pos)
{
if (insert_cur_pos->key > cur_node->key)
break;
insert_pre_pos = insert_cur_pos;
insert_cur_pos = insert_cur_pos->next;
}
if (!insert_pre_pos)
insert_pre_pos = &dumy_node;
Node *temp_node = cur_node->next;
cur_node->next = insert_pre_pos->next;
insert_pre_pos->next = cur_node;
cur_node = temp_node;
}
return dumy_node.next;
}
int swapNode( node * &first, node * &second)
{
//first we will declare the
//previous of the swaping nodes
node *firstprev=NULL;
node*secprev=NULL;
node*current=head;
//set previous first
while(current->next!=first)
{
current=current->next;
}
firstprev=current;
//seting 2nd previous
while(current->next!=second)
{
current=current->next;
}
// swap datas, assuming the payload is an int:
int tempdata = first->data;
first->data = second->data;
second->data = tempdata;
//swaping next of the nodes
firstprev->next=second;
secprev->next=first;
}
Here is my Merge sort realisation, with O(N*logN) time complexity and constant additional space. Uses C++11
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
typedef pair<ListNode*, ListNode*> PP;
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (head==nullptr)return head;
if (head->next==nullptr) return head;
if (head->next->next==nullptr){
if (head->val<=head->next->val){
return head;
}
else {
ListNode* second=head->next;
second->next=head;
head->next=nullptr;
return second;
}
}else {
PP splitted=split(head);
return merge(sortList(splitted.first),sortList(splitted.second));
}
}
private:
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode * head=new ListNode(0);
ListNode * current=head;
if (l1==nullptr)return l2;
if (l2==nullptr)return l1;
do {
if (l1->val<=l2->val){
current->next=l1;
l1=l1->next;
}else{
current->next=l2;
l2=l2->next;
}
current=current->next;
}while (l1!=nullptr && l2!=nullptr);
if (l1==nullptr)current->next=l2;
else current->next=l1;
return head->next;
}
PP split(ListNode* node){
ListNode* slow=node;
ListNode* fast=node;
ListNode* prev;
while(fast!=nullptr){
if (fast->next!=nullptr){
prev=slow;
slow=slow->next;
fast=fast->next;
}else break;
if(fast->next!=nullptr){
fast=fast->next;
}
else break;
}
prev->next=nullptr;
return {node,slow};
}
};
Use std::list<T>::sort method. Or if you're being precocious, std::forward_list<T>::sort.
Why re-invent the wheel.
I've been trying to figure out how to reverse the order of a doubly-linked list, but for some reason, in my function void reverse() runs while loop once and then crashes for some reason. To answer some questions ahead, I'm self-teaching myself with my brothers help. This isn't all of the code, but I have a display() function which prints all nodes chronologically from start_ptr and a switch which activates certain functions like
case 1 : add_end(); break;
case 2 : add_begin(); break;
case 3 : add_index(); break;
case 4 : del_end(); break;
case 5 : del_begin(); break;
case 6 : reverse(); break;
This is the geist of my code:
#include <iostream>
using namespace std;
struct node
{
char name[20];
char profession[20];
int age;
node *nxt;
node *prv;
};
node *start_ptr = NULL;
void pswap (node *pa, node *pb)
{
node temp = *pa;
*pa = *pb;
*pb = temp;
return;
}
void reverse()
{
if(start_ptr==NULL)
{
cout << "Can't do anything" << endl;
}
else if(start_ptr->nxt==NULL)
{
return;
}
else
{
node *current = start_ptr;
node *nextone = start_ptr;
nextone=nextone->nxt->nxt;
current=current->nxt;
start_ptr->prv=start_ptr->nxt;
start_ptr->nxt=NULL;
//nextone=nextone->nxt;
while(nextone->nxt!= NULL)
{
pswap(current->nxt, current->prv);
current=nextone;
nextone=nextone->nxt;
}
start_ptr=nextone;
}
}
Try this:
node *ptr = start_ptr;
while (ptr != NULL) {
node *tmp = ptr->nxt;
ptr->nxt = ptr->prv;
ptr->prv = tmp;
if (tmp == NULL) {
end_ptr = start_ptr;
start_ptr = ptr;
}
ptr = tmp;
}
EDIT: My first implementation, which was correct but not perfect.
Your implementation is pretty complicated. Can you try this instead:
node * reverse(Node * start_ptr)
{
Node *curr = start_ptr;
Node * prev = null;
Node * next = null;
while(curr)
{
next = curr->nxt;
curr->nxt = prev;
curr->prv = next;
prev = curr;
curr = next;
}
return start_ptr=prev;
}
Here is my updated solution:
node * reverse()
{
node *curr = start_ptr;
node * prev = NULL;
node * next = NULL;
while(curr)
{
next = curr->nxt;
curr->nxt = prev;
curr->prv = next;
prev = curr;
curr = next;
}
return start_ptr=prev;
}
The logic was correct. But the issue was that I was accepting in input argument start_ptr. Which means that I was returning the local copy of it. Now it should be working.
You can simplify your reverse() quite a bit. I'd do something like this:
void reverse()
{
if(start_ptr == NULL)
{
cout << "Can't do anything" << endl;
}
else
{
node *curr = start_ptr;
while(curr != NULL)
{
Node *next = curr->next;
curr->next = curr->prev;
curr->prev = next;
curr = next;
}
start_ptr = prev;
}
}
Explanation: The basic idea is simply to visit each Node and swap the links to previous and next. When we move curr to the next Node, we need to store the next node so we still have a pointer to it when we set curr.next to prev.
Simple solution. reverses in less than half a number of total iterations over the list
template<typename E> void DLinkedList<E>::reverse() {
int median = 0;
int listSize = size();
int counter = 0;
if (listSize == 1)
return;
DNode<E>* tempNode = new DNode<E>();
/**
* A temporary node for swapping a node and its reflection node
*/
DNode<E>* dummyNode = new DNode<E>();
DNode<E>* headCursor = head;
DNode<E>* tailCursor = tail;
for (int i = 0; i < listSize / 2; i++) {
cout << i << "\t";
headCursor = headCursor->next;
tailCursor = tailCursor->prev;
DNode<E>* curNode = headCursor;
DNode<E>* reflectionNode = tailCursor;
if (listSize % 2 == 0 && listSize / 2 - 1 == i) {
/**
* insert a dummy node for reflection
* for even sized lists
*/
curNode->next = dummyNode;
dummyNode->prev = curNode;
reflectionNode->prev = dummyNode;
dummyNode->next = reflectionNode;
}
/**
* 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;
if (listSize % 2 == 0 && listSize / 2 - 1 == i) {
/**
* remove a dummy node for reflection
* for even sized lists
*/
reflectionNode->next = curNode;
curNode->prev = reflectionNode;
}
/**
* Reassign the cursors to position over the recently swapped nodes
*/
tailCursor = curNode;
headCursor = reflectionNode;
}
delete tempNode, dummyNode;
}
template<typename E> int DLinkedList<E>::size() {
int count = 0;
DNode<E>* iterator = head;
while (iterator->next != tail) {
count++;
iterator = iterator->next;
}
return count;
}
I suggest maintaining a link to the last node.
If not, find the last node.
Traverse the list using the "previous" links (or in your case, prv).
There is no need to actually change the links around. Traversing using the prv pointer will automatically visit the nodes in reverse order.
Look at
valuesnextone=nextone->nxt->nxt;
Here nextone->nxt can be null.
Apart from that, try to use pointers to pointers in the swap function.
Your pswap function is wrong
your should swap the pointer not try to create temporary objects and swap them.
Should be like that (there might be other mistake later)
void pswap (node *&pa, node *&pb)
{
node* temp = pa;
pa = pb;
pb = temp;
return;
}
A very simple and O(n) solution using two pointers:
start = head of the doubly LL
struct node *temp, *s;
s = start;
while(s != NULL){
temp = s->prev;
s->prev = s->next;
s->next = temp;
s = s->prev;
}
//if list has more than one node
if(current != NULL){
start = temp->prev;
}
My code for reversing doubly linked list,
Node* Reverse(Node* head)
{
// Complete this function
// Do not write the main method.
if(head != NULL) {
Node* curr = head;
Node* lastsetNode = curr;
while(curr != NULL) {
Node* frwdNode = curr->next;
Node* prevNode = curr->prev;
if(curr==head) {
curr->next = NULL;
curr->prev = frwdNode;
lastsetNode = curr;
}
else {
curr->next = lastsetNode;
curr->prev = frwdNode;
lastsetNode = curr;
}
curr = frwdNode;
}
head = lastsetNode;
}
return head;
}
I thought I'd add a recursive solution here.
node* reverse_and_get_new_head(node* head) {
if (head == nullptr) { return nullptr; }
// This can be avoided by ensuring the initial,
// outer call is with a non-empty list
std::swap(head->prev, head->next);
if (head->prev == nullptr) { return head; }
return reverse_and_get_new_head(head->prev);
}
void reverse() {
start_ptr = reverse_and_get_new_head(start_ptr);
}