时间: 2020-06-16 12:51
/*********************************
版本一
********************************/
/*一般方法, 假定第一个位置为最小值点, 遍历后续所有节点找出最小值,
然后与第一个未处理的点进行交换*/
for (int i = 0; i < len - 1; ++i) {
int pos = i; //记录当前准备处理的节点
for (int j = i + 1; j < len; ++j) {
pos = arr[j] < arr[pos] ? j : pos; //寻找最小值点
}
if (i != pos) { //无需额外申请空间达到两数交换的效果, 异或法
arr[i] = arr[i] ^ arr[pos];
arr[pos] = arr[i] ^ arr[pos];
arr[i] = arr[i] ^ arr[pos];
}
}
/*********************************
版本二
********************************/
/*在每一次的遍历过程中同时寻找出当前所有未处理节点中的最小值与最大值节点,
然后分别与当前未处理的第一个节点和最后一个节点进行交换, 同时缩小遍历范围*/
for (int i = 0, j = len - 1; i < j; ++i, --j) {
int min = i; //记录当前准备处理的第一个节点
int max = j; //记录当前准备处理的最后一个节点
for (int k = i; k <= j; ++k) {
if (arr[k] < arr[min]) { //寻找最小值点
min = k;
}
else if (arr[k] > arr[max]) { //寻找最大值点
max = k;
}
}
if (i != min) { //无需额外申请空间达到两数交换的效果, 异或法
arr[i] = arr[i] ^ arr[min];
arr[min] = arr[i] ^ arr[min];
arr[i] = arr[i] ^ arr[min];
}
if (j != max) { //无需额外申请空间达到两数交换的效果, 异或法
arr[j] = arr[j] ^ arr[max];
arr[max] = arr[j] ^ arr[max];
arr[j] = arr[j] ^ arr[max];
}
}
总结:
若进行异或操作的两个对象处于同一块内存空间中 (也就是内存中二者的地址相同) , 最终的交换结果将是0, 因为二者其实是同一个对象, 本身与本身进行异或操作结果为零, 零和零的异或操作也将是零, 所以最终结果就是零.