Swapping variables without additional space
Posted by tekpool on December 3, 2006
Swapping variables is a very common operation used it tons of algorithms like sorting etc. The most common and obvious technique is using of a temporary variable to swap values between two variables
void swap(int &i, int &j)
{
int temp = i;
i = j;
j = temp;
}
Instead of writing a separate function for each data type, you could write a MACRO or templatize the function.
Swapping without using a temporary variable is an age old trick and there are a few ways to do this. You could use of the basic arithmetic operations like +,-,/,*
1: void swap(int &i, int &j)
2: {
3: i=i+j;
4: j=i-j;
5: i=i-j;
6: }
The technique involves storing the sum of variables in one of them and then extracting it back by subtracting the other number. There are different variants to this technique. E.g, instead of starting by storing the sum, you could store the difference, product or the quotient. The last two could lead you to round-off and integer division errors. However all of them have one fundamental flaw. Its in line 3, and the issue is that this could lead to an overflow error.
This is another technique the gets you around these issues; the XOR Swapping technique
void swap(int &i, int &j)
{
i = i ^ j;
j = j ^ i;
i = i ^ j;
}
This is an elegant technique and should work well with any primitive data type and you could write a simple MACRO like
#define SWAP(i, j) (((i) ^= (j)), ((j) ^= (i)), ((i) ^= (j)))
Although, the XOR technique gets rid of the other issues like overflow and round off errors that we encountered in the previous technique, the lands in into yet another issues; This does not work when you try to swap the same memory location. However if can get around this by a simple ‘if’ check or a more elegant OR check like
#define SWAP(i, j) ( (i==j) || ((i) ^= (j)), ((j) ^= (i)), ((i) ^= (j)))
The first OR condition (i == j) is checked before the actual SWAP. (You do not need a SWAP if the both memory locations hold the same data)
Aatif said
void swap(int &i, int &j)
{
i = i ^ j;
j = i ^ j; //rather than j ^ i;
i = i ^ j;
}
logan said
Aatif, i ^ j and j ^ i are the same. It makes no difference.
feli said
Alternatively you can do this
void swap(int &i, int &j)
{
i = i + j;
j = i – j;
i = i – j;
}
Zaman Bakshi said
You have used C or C++ for this problem. if I had been the interviewer I would have cut your marks. All the techniques you have just mentioned lead to an undefined behaviour. The first one for negatives and the later ones for the resultants going out of bounds. I hope you add a comment stating that it is just an algorithm irrespective of the programming language used.
st0le said
Try This…In ONE SINGLE LINE…
a^=b^=a^=b;
st0le said
void swap(int &a, int &b)
{
a^=b^=a^=b;
}