快速排序
1.排序思路
(1)快速排序本质相当于找到数组中的“基准数”在数组中的“中间”位置,然后从“中间”位置为分界线,分割成“左右”两个小的数组,在这个小的数组中继续递归上述操作。
(2)所谓“中间”位置:将比基准数大的数据放在基准数右边,把基准数小的放在左边。
(3)所谓“基准数”:随便在数组两端选择一个,一般选择最左边的数。
2.代码思路
(1)其实所有排序的本质是找到数组中的数在一个“合适”的位置的过程:快速排序就是在找基准数在数组“中间”位置的过程,可以首先想到指针。
(2)如果选择最左的数作为基准数,则从右到左比较,反之亦然。
(3)如果比基准数大(或等于)则移动最右端的指针指向左一步,并用指针处的值和基准数比较,直到遇到比基准数小的数,则停止移动指针。
(4)待(3)步骤停止移动指针后,从左到右进行比较,如果比基准数小(或等于),则移动最左端的指针向右移动一步,并用指针处的值和基准数比较,直到遇到比基准数大的数,则停止移动指针。
(5)此时如果指针未相遇则将指针停留所在的数进行交换,然后重复(3)和(4)步骤,直到指针重合。
(6)当指针重合,退出(3)(4)(5)循环,将指针重合处的数和基准数进行交换位置。
(7)此时完成了一次将数组中比基准数小的数放在左边,将比基准数大的数放在右边的过程,为这个基准数找到了一个“中间”位置。
(8)以指针重合处作为分隔处,将隔开的“左边部分”的数组和“右边部分”的数组继续循环(4)(5)(6)(7)(8)步骤,直到不可分割为止。
3.代码示例
@Test
public void testQuickSort() {
int[] arr = {1111,222,31231,12312111,1231231231,123};
qs(arr, 0, arr.length - 1);
System.err.println(Arrays.toString(arr));
}
public static void qs(int[] arr, int left, int right) {
if (left < right) {
//低位指针
int low = left;
//高位指针
int high = right;
//选择基准数
int key = arr[left];
while (low < high) {
//从右到左如果比基准数大于等于左移,遇到小于基准数就停下来
while (low < high && arr[high] >= key) {
high--;
}
//从左到右如果比基准数小于等于就右移,遇到大于基准数就停下来
while (low < high && arr[low] <= key) {
low++;
}
//交换2个指针处对应的数
if (low < high) {
int temp = arr[high];
arr[high] = arr[low];
arr[low] = temp;
}
}
//交换重合数和基准数
arr[left] = arr[low];
arr[low] = key;
qs(arr, left, low - 1);
qs(arr, low + 1, right);
}
}
ps:默认排序为升序