一个数组int[] numArr = {0,1,2,3,4,5,6,7,8,9},将其进行倒叙排列为{9,8,7,6,5,4,3,2,1,0},也就是将数组进行反转。这里分列两种方式:由外入里、由里到外。算法的关键在于确定交换的元素边界,当数组为偶数时,头尾交换正适合,而为奇数时,则存在中间元素。
- 由外到里
1、变量交换,通过中间变量num1,num2进行预存numArr[i]和numArr[len - 1 - i],然后进行交换numArr[i]和numArr[len - 1 - i]。
public static void swap1(int[] numArr) {
final int len = numArr.length;
int count, num1, num2, index;
if(len % 2 == 0) {
count = len / 2;
} else {
count = (len - 1) / 2;
}
for(int i = 0; i < count; i++) {
index = len - 1 - i;
num1 = numArr[i];
num2 = numArr[index];
numArr[i] = num2;
numArr[index] = num1;
}
}
2、不同中间变量交换两个数组元素
public static void swap2(int[] numArr) {
final int len = numArr.length;
int count, index;
if(len % 2 == 0) {
count = len / 2;
} else {
count = (len - 1) / 2;
}
for(int i = 0; i < count; i++) {
index = len - 1 - i;
numArr[i] = numArr[i] ^ numArr[index];
numArr[index] = numArr[i] ^ numArr[index];
numArr[i] = numArr[i] ^ numArr[index];
}
}
- 由里到外
在上面的循环之中,数组下标由小到大,所以由外到里进行交换,而换一种方式,数组小标由大到小,则是由里到外。
1、变量交换
public static void swap3(int[] numArr) {
final int lastIndex = numArr.length - 1;
int num1, num2, index = lastIndex - 1 >> 1;
for(; index >= 0; index--) {
num1 = numArr[index];
num2 = numArr[lastIndex - index];
numArr[index] = num2;
numArr[lastIndex - index] = num1;
}
printArr(numArr);
}
2、不同中间变量交换两个数组元素
public static void swap4(int[] numArr) {
final int lastIndex = numArr.length - 1;
for(int index = lastIndex - 1 >> 1; index >= 0; index--) {
numArr[index] = numArr[index] ^ numArr[lastIndex - index];
numArr[lastIndex - index] = numArr[index] ^ numArr[lastIndex - index];
numArr[index] = numArr[index] ^ numArr[lastIndex - index];
}
printArr(numArr);
}
总结
数组元素反转关键在于for循坏边界确定,同时优化元素变量交换,通过异或运算符来减少变量的使用,此外lastIndex - 1右移1位等同于除以2,而lastIndex作为numArr数组元素最后下标,当为奇数时,可以减少一次交换,即numArr[index] ==numArr[lastIndex - index]。