快排
经典快排
<=X | X | >X |
经典快排中间是一个数,左边是小于等于X的范围,右边是大于X的数。可以用荷兰国旗问题来改进快速排序。改进之后的快排:
<X | =X | >X |
荷兰国旗问题快排算法如下:
package test_01;
import java.util.Arrays;
public class NetherlandsFlag {
public static int[] partition(int[] arr, int l, int r, int cur) {
int less = l-1;
int more = r+1;
//int index = l;
while (l < more) {
if (arr[l] < cur) {
swap(arr, ++less, l++);
}else if (arr[l] > cur) {
swap(arr, --more, l);
}else {
l++;
}
}
return new int[] {less+1,more-1};
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {2,4,5,3,1,6,7,5,8,9};
int[] a = partition(arr,0,arr.length-1,5);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(arr));
}
}
- 时间复杂度O(N*logN),额外空间复杂度O(logN)。
另外一种写法的快排算法:
package test_01;
import java.util.Arrays;
public class QuickSort {
public static void quickSort(int[] arr) {
if (arr==null || arr.length<2) {
return;
}
quickSort(arr, 0, arr.length-1);
}
public static void quickSort(int[] arr,int l, int r) {
if (l < r) {
int[] p = partition(arr, l, r);
quickSort(arr, l, p[0]-1);
quickSort(arr, p[1]+1, r);
}
}
public static int[] partition(int[] arr, int l, int r) {
int less = l-1;
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
}else if (arr[l] > arr[r]) {
swap(arr, --more, l);
}else {
l++;
}
}
swap(arr, more, r);
return new int[] {less+1, more};
}
public static void swap(int[] arr,int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {2,3,5,1,67,8,45};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
}
堆排序(堆排序非常重要)
- 堆结构的heapInsert与heapify
- 堆结构的增大和减少
- 如果只是建立堆的过程,时间复杂度为O(N)
- 优先级队列结构,就是堆结构
代码如下:
package test_01;
import java.util.Arrays;
public class HeadSort {
public static void heapSort(int[] arr) {
if (arr==null || arr.length<2) {
return;
}
for (int i=0; i<arr.length; i++) {
heapInsert(arr, i);
}
int size = arr.length;
swap(arr, 0, --size);
while (size > 0) {
heapify(arr, 0 ,size);
swap(arr, 0, --size);
}
}
public static void heapInsert(int[] arr, int index) {
while (arr[index] > arr[(index-1)/2]) {
swap(arr, index, (index-1)/2);
index = (index-1)/2;
}
}
public static void heapify(int[] arr, int index, int size) {
int left = index*2+1;
while (left < size) {
int largest = left+1 < size && arr[left+1] > arr[left] ? left+1:left;
largest = arr[largest] > arr[index] ? largest:index;
if (largest == index) {
break;
}
swap(arr, largest, index);
index = largest;
left = index*2+1;
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {4,12,6,23,7,9,1};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
}
- 时间复杂度O(N*logN),额外空间复杂度O(1)。