题目:给定一个已经降序排好序的正数数组,要求按「最小、最大、次小、次大……」的顺序重新排序。期望的时间复杂度为O(n),空间复杂度为O(1),即不能申请额外的数组。
例如:输入[7,6,5,4,3,2,1],输出[1,7,2,6,3,5,4]。
分析:该题有多种方法可以解答,在这里给出一个不超过应届毕业生知识范围的写法。
private static void ReCardsSortInPlace(int[] array) { if (array == null) throw new ArgumentNullException(); if (array.Length < 2) return; if (array.Length == 2) { int temp = array[0]; array[0] = array[1]; array[1] = temp; return; } //因为循环不变式的初始条件是N>=3所以,当N<=2时只能靠手调了。 int swapTemp, swapTemp1, length = array.Length - 1, right = length; int k = right; int rightCount = right - 1; //循环进入条件,N>=3,结束条件,从数组右侧开始,当调整的位置的数量大于N/3时 while ((2 * (length - right + 1)) <= right) { //循环初始条件 k = right; swapTemp1 = array[right]; do { k = ReIndex(k, length); swapTemp = array[k]; array[k] = swapTemp1; swapTemp1 = swapTemp; } while (right != k); //由于数组是递减的,所以调整过的数组一定会满足以下条件 while (array[rightCount] > array[ReIndex(rightCount, length)]) { rightCount--; } right = rightCount;//将未调整的循环的初始值重新赋予right变量 rightCount = right - 1; } } private static int ReIndex(int index, int length) { if (index <= length / 2) return (2 * index + 1 > length) ? 2 * index : (2 * index + 1); else return (2 * (length - index)); }