为什么要j(右)游标必需先动?
因为j停下来后i(左)可能会直接碰到j,此时j可直接与left交换, 因为j所指的一定比left小。
如果i先动,j还没找到比base小的值, 就因碰到i停下,此时如果j所指比base大交换后就出错了。? ?我选取的是第一个元素作为base,如果是最后一个则反过来。
public static void quickSort(int []arr,int left,int right){
//当分组后的数组只剩下一个元素,则直接返回
if (left >= right){
return;
}
//以数组的第一个元素作为基准元素
int base = arr[left];
int l = left;
int r = right;
//这个循环是待l与r相遇的元素,左边小于基准元素,右边大于基准元素
while (l<r){
//右指针左移直到遇到小于base的元素
while(r>l&&arr[r]>=base){
r--;
}
//左指针右移,直到遇到大于base的元素
while (l<r&&arr[l]<=base){
l++;
}
//此时右指针指向的值小于base,左指针指向的值大于base
//交换两个所指元素
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
//相遇后将这个元素与基准元素交换。
//则基准元素左边下于它,右边大于它。则这个元素排序完成
arr[left] = arr[l];
arr[l] = base;
//递归实现其他元素的排序
quickSort(arr,left,r-1);
quickSort(arr,r+1,right);
}
1、选出一个key,一般是最左边或是最右边的。
2、起始时,left指针指向序列开头,cur指针指向left+1。
3、若cur指向的内容小于key,则left先向后移动一位,然后交换left和cur指针指向的内容,然后cur指针++;若cur指向的内容大于key,则cur指针直接++。如此进行下去,直到cur到达right位置,交换left和key(i)的值。
再这个排序过程中left指向的元素及其左边的所有元素都是小于等于key的,它右边的与cur之间的则是大于key的元素。
经过一次单趟排序,最终也能使得key左边的数据全部都小于key,key右边的数据全部都大于key。
?
public static void quickSort2(int []arr, int left, int right){
if (left>=right){
return;
}
int base = arr[left];
int i = left;
int curv = left+1;
while (curv<=right){
if (arr[curv]<base){
int temp = arr[++left];
arr[left] = arr[curv];
arr[curv] = temp;
}
curv++;
}
int temp = arr[left];
arr[left] = base;
arr[i] = temp;
quickSort2(arr, i, left-1);
quickSort2(arr,left+1,right);
}
利用完全二叉树构建 大顶堆(父节点的值大于或等于其左右孩子的值)。
堆顶元素与堆底元素进行互换,互换完成后,堆底元素(最底层的最右边的元素)不再参与构建(这个元素已经排好序了)。
public static void main(String[] args) {
int [] arr = new int[]{1,3,2,4,8,3};
//先构建大顶堆
for (int p = arr.length-1; p >=0 ; p--) {
abjust(arr,p,arr.length);
}
//此时大顶堆的堆顶是第一大的
for (int i = arr.length-1; i >=0; i--) {
//将堆顶和为排序区域第一个交换
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
//此时大顶堆的堆顶不符合大顶堆性质,则需要一次修改变为大顶堆
abjust(arr,0,i);
}
System.out.println(Arrays.toString(arr));
}
public static void abjust(int []arr, int parent, int length){
int child = parent*2+1;
while (child<length){
int rChild = child+1;
if (rChild<length&&arr[rChild]>arr[child]){
child++;
}
if (arr[child]>arr[parent]){
int temp = arr[child];
arr[child] = arr[parent];
arr[parent] = temp;
parent = child;
child = child*2+1;
}else {
break;
}
}
}
?
????????????????