472,127 Members | 2,043 Online

# Function that can swap elements in a singly linked list

3
Some one help me write a function that can swap elements in a singly linked list?Having a problem swapping the elements without, loosing some of the data?
Mar 5 '10 #1
18 17655
Assuming you can get pointers to the data of the two nodes you want to swap (call them a and b), I'd do the following:
1. In your function, create a variable to temporarily hold the value of b (if you're using an int, int temp = b).
2. Assign the value of a to the value of b (b = a).
3. Assign the value of a to the temporary variable (a = temp).
Mar 5 '10 #2
jkmyoung
2,057 Expert 2GB

What you need to do is find the nodes before them. Say your nodes are a, b.
Find the nodes linking to them, say beforeA, beforeB.

beforeA.next = b;
beforeB.next = a;
So now you've switched the links to them. Now, you must switch the links after the nodes.
temp = a.next;
a.next = b.next;
b.next = temp;

Also, you have to take into account: what if there is no beforeA, or beforeB? (eg one of them is the head?) See how this works out, and then try to figure out your special cases. Don't forget to check if a = b; then you don't have to do any work!
Mar 5 '10 #3
What is the necessity of swapping the nodes themselves? While swapping the values isn't truly the same as swapping the nodes, the end result is the same without all the extra pointer assignments.

A check to see if a already equals b would save you a lot of time though.
Mar 5 '10 #4
jkmyoung
2,057 Expert 2GB
I guess it depends on the composition of the nodes; whether the data is easily copyable or depends on the context of the node.

Mar 5 '10 #5
Ah, so you're saying that it might be faster to swap the pointers around if the data stored in the linked list is a complex type like a class.
Mar 5 '10 #6
weaknessforcats
9,208 Expert Mod 8TB
This is not that hard.

If you have node addresses A B C D and you want to swap B and C what you do is:

1) Traverse to B. During this traverse, save the address of the current node in TEMP before you go the the next node. When you get to B, TEMP will have the address of A.

2) TEMP->NEXT (remember TEMP is the address of A) is assigned B->NEXT. Now you have A pointing to C.

3) B->NEXT is assigned B->NEXT->NEXT (B->NEXT is C. Therefore,
B->NEXT->NEXT is really C->NEXT,which is D).

It looks like this:

TEMP->NEXT = B->NEXT;
B->NEXT = B->NEXT->NEXT;
Mar 5 '10 #7
Right, but the point we were discussing before was that if you have a simple data type, it would be faster and simpler to just swap out the values of the nodes.
Mar 5 '10 #8
Bito
3
Am trying to write a program that prompts the user to enter integer data, i store it in a linked list then i sort it into ascending order. Am using the selection sort function to arrange the data and its supposed to call the swap function, i want to swap the last and largest element in the linked list. but i do not know how to write that function.these are my two functions to find the last and largest elements in the linked list
Expand|Select|Wrap|Line Numbers
1. Node * maxPtr(Node * &list,int n)
2. {
3.     int i = 0;
4.     Node * mPtr = list;
5.     Node * iPtr = list -> next;
6.     while( i< n)
7.     {
8.            if(iPtr -> data > mPtr -> data)
9.               {
10.                    mPtr = iPtr;
11.               }
12.               i++;
13.               iPtr = iPtr ->next;
14.    }
15.    return mPtr;
16. }
17.
18. Node * lastPtr(Node * &list,int n)
19. {
20.     Node * newp = list;
21.     Node * lastp;
22.     int i = 0;
23.     while(i < n)
24.       {
25.      if(newp -> next  == NULL)
26.         lastp = newp;
27.       }
28.       i++;
29.       newp = newp -> next;
30.       return lastp;
31.
32. }
33.
Am left with writing the swap function and need help with that..
Mar 6 '10 #9
Banfa
9,065 Expert Mod 8TB
In my experience if you are receiving a series of values and storing them in a list that finally has to be ordered it is often just as easy to put them in the list in the right order in the first place as to sort the list after you have all the values.
Mar 6 '10 #10
Bito
3
so how would i be able to do that?? and can u help me with this invariance questionas well..

What is the invariance of the algorithm??

int power(int n, int p)
// Pre: p >= 0
// Post: returns n raised to the power p
{
int result = 1;
int i = 0;
while (i != p)
{
result = result * n;
i++;
}
return result;
}

am abit confused on what we are supposed to do.. Is it right to say that the invariance is n^p since we are going to multiply n by its self n times??
Mar 6 '10 #11
weaknessforcats
9,208 Expert Mod 8TB
Right, but the point we were discussing before was that if you have a simple data type, it would be faster and simpler to just swap out the values of the nodes.
How do you know this would be faster?

If you have an int, that would be the size of a pointer. Swapping trhe int and swapping the next pointer of the nodes is about the same.

Swapping floating point will be very much slower. The variables are bigger and have rounding considerations.

Swapping char will cause a conversion to int and then a conversion back to char.
Mar 6 '10 #12
jkmyoung
2,057 Expert 2GB
eg. pseudo
Expand|Select|Wrap|Line Numbers
2. int newNodeValue;
3. Node newNode = new Node(newNodeValue);
4. Node curr, next;
6. if (curr == null){
8.   return;
9. }
10. if (curr.value > newNodeValue){
14.    return;
15. }
16. next = curr.next();
17. while (next != null && next.value < newNodeValue){
18.   curr = next;
19.   next = curr.next;
20. }
21. curr.next = newNode;
22. if(next != null){// end of list
23.   newNode.next = next;
24. }
25.
Mar 8 '10 #13
weaknessforcats
9,208 Expert Mod 8TB
Actually, I would improve this by writing a function with two arguments that are pointers to node that would insert the second pointer after the first pointer in the list.

What this will do is isolate all this next/prev pointer fiddling to one function. Call that function from your AddNode.

Note that ot insert at the front of the list, you add your insert-after function using the adress of the first node in the list as the second argument.

Then, write a second function to create a new node on the heap and return a pointer to that node. This function will have the value of the node as the first argument.

Expand|Select|Wrap|Line Numbers
2. {
3.
4. Node* temp = FindEndOFList();         //write this too
5. Node* newNode = CreateNode(NewValue);
6. InsertAfter(temp, newNode);
7. }
By having your functions do only one thing, you can use them more often.
Mar 8 '10 #14
jkmyoung
2,057 Expert 2GB
In response to post 11: Sorry, do you have another definition of invariance? It sounds like what wouldn't change in the function regardless of the values of p and n.

In response to post 12: Switching links requires at most 4 link switches, as well as a lot of special case testing.

In response to post 14: Then the insertions would not be sorted. The only reason for post 13 was for sorted insertion. Could write a simplifying function called Node FindGreatestNodeLessThan(int value), which returns the last node with value smaller than the given value. eg:
Expand|Select|Wrap|Line Numbers
2.   Node newNode = new Node(newValue);
3.   Node last = FindGreatestNodeLessThan(newValue);
4.   if( last == null){
7.      return;
8.   }
9.   newNode.next = last.next;
10.   last.next = newNode;
11. }
But this is only useful if FindGreatestNodeLessThan can be reused somewhere. The function FindGreatestNodeLessThan would require pointer swapping anyways.
Mar 8 '10 #15
whodgson
542 512MB
Why can`t a single pointer be set to the head and a second pointer set to the tail and then the two pointers be swapped using the swap function from the algorithm header. If it works properly with a string or array or vector why would it not work with a list?
Mar 9 '10 #16
jkmyoung
2,057 Expert 2GB
@whodgson
It's not just a list, it's a Linked List.
Mar 9 '10 #17
Banfa
9,065 Expert Mod 8TB
Arguambly a <list> is a linked list or at least most commonly is implemented as one although a quick glance at the standard doesn't seem to indicated that it is specified as being implemented that way.

whodgson the thing being discussed in this thread is a home grown (linked) list not an STL list. This is may or may not be being implemented in C++ however what is certain is that there is no suggestion that this home grown list conforms to the requirements for a standard container and therefore none of the standard algorithms can be expected to work on them.

Additionally look at the definition of swap, it swaps the values of 2 objects, in this case that would include all the pointers defined in the node effectively resulting in no change (the data would be stored in different locations but the list would ultimately have the same order.

swap does not work on pointers (or iterators) but objects and for that reason it can not be used on a linked list, or iterators into and standard container or pointers.
Mar 9 '10 #18
whodgson
542 512MB
I think I should not have butted in as I did -- quite rude really.
But thank you Banfa for your explanation. I intend to study it further.
p.s. I apparently mistakenly thought that all lists were at least singly linked.
Mar 10 '10 #19