不用中间变量实现交换swap的问题

我们在实现交换的时候一般都是用一个中间变量来暂存:

void swap(int& a, int& b) {
	int temp = a; //exchange  
	a = b;
	b = temp;
}
类似于这样,然而也有不用中间变量的方法:

void swap(int& a, int& b) {
	a += b;
	b = a - b;
	a -= b;
}

还有这样:

void swap(int& a, int& b) {
	a = a^b;
	b = a^b;
	a = a^b;
}

这种取巧的方法相信大家都见过,可是,他们是有缺陷的!
是的,我被坑了,在今天手写了个快排,需要随机选一个数和第一个元素交换,一开始是用的异或交换,结果输出错误:

后面发现似乎是swap的问题,然后写了三个swap来测试:

#include<iostream>
#include<ctime>
#include<stdlib.h>
using namespace std;

void swap2(int& a, int& b) {
	a = a^b;
	b = a^b;
	a = a^b;
}

void swap1(int& a, int& b) {
	int temp = a; //exchange  
	a = b;
	b = temp;
}
void swap3(int& a, int& b) {
	a += b;
	b = a - b;
	a -= b;
}


void quicksort(int* a, int left, int right) {
	if (left < right) {
		int ra = left + (right - left + 1)*rand() / (RAND_MAX + 1);
		swap1(a[left], a[ra]);
		int x = a[left];
		int l = left;
		int r = right;
		while (true) {
			while (l < r&&a[r] >= x)
				r--;
			if (l < r)
				a[l++] = a[r];
			while (l < r&&a[l] < x)
				l++;
			if (l < r)
				a[r--] = a[l];
			if (l >= r)
				break;
		}
		a[l] = x;
		quicksort(a, r + 1, right);
		quicksort(a, left, r - 1);
	}
}


int main() {
	int a[] = { 3,1,2,0,7,5,6,9,4,8 };
	srand(time(0));
	quicksort(a, 0, sizeof(a) / sizeof(int) - 1);
	for (int i = 0; i < sizeof(a) / sizeof(int); i++)
		printf("%d\t", a[i]);
	cin.get();
	return 0;
}

swap1的结果是正确的:


而swap3也错了:



注意到都是多了0元素。后面经过我的探究发现了问题所在!

就是这种交换不能和自己本身交换!

就是这种交换不能和自己本身交换!

就是这种交换不能和自己本身交换!

重要的话说三遍。当和本身交换时,他的值会为零!在分治方法中最好不要使用这种交换,因为他可能会分到最后为一个元素和它本身交换。其实最好使用swap1虽然可能增加了消耗,但是程序bug会更少。

猜你喜欢

转载自blog.csdn.net/YoungStunner/article/details/50826185