随机快排
时间复杂度O(N*logN)
空间复杂度O(logN):最好情况为O(logN),二分法打断点;最坏情况下为O(N),每个都要打断点。
样本状况
一个样本状况会导致算法的复杂度有所变化,可以采用两种方法:
1、随机样本选取来划分
2、哈希函数
堆
堆就是完全二叉树。
大根堆
任何一棵子树的最大值都是树的头部。
小根堆
任何一棵子树的最小值都是树的头部。
堆排序
1、先生成一个大根堆。
2、然后把大根堆的根与最后一个值交换。
3、让堆的大小-1,再做heapfiy的过程,重新形成大根堆。
4、再把最大值放到最后面。以此类推。
作业
1、完成荷兰国旗问题。
2、经典快排、随机快排
3、heapinsert 和 heapify
heapinsert:插入最大堆,是建立堆的一个操作。
heapify:改变数组中的某一值重新调整为最大堆。
作业完成
1、荷兰国旗问题
package niuke2;
public class helanguoqi {
public static void helan(int[] arr, int num) {
int left = 0;
int right = arr.length - 1;
int less = left - 1;
int more = right + 1;
while(left < more) {
if(arr[left] < num) {
swap(arr,++less, left++);
}else if(arr[left] > num) {
swap(arr, --more, left);
}else {
left++;
}
}
}
//交换元素
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
//打印数组,测试用。
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
}
printarr(res);
System.out.println("num = " + res[3]);
helan(res,res[3]);
printarr(res);
}
}
2、经典快排
经典快排思路跟荷兰国旗问题一样,只是注意要最后分区时要换位置。最坏情况:O(N2),最好情况:O(NlogN)。
package niuke2;
import java.util.Arrays;
public class QuickSort {
public static void quickSort(int[] arr) {
if(arr.length <= 1)
return;
quicksort(arr, 0, arr.length-1);
}
public static void quicksort(int[] arr, int left, int right) {
if(left < right) {
int p = quickSort(arr,left,right);
quicksort(arr, left, p-1);
quicksort(arr, p+1, right);
}
}
public static int quickSort(int[] arr, int left, int right) {
if(left >= right)
return 0;
int num = arr[right];
int less = left - 1;
int more = right;
while(left < more) {
if(arr[left] < num) {
swap(arr,++less,left++);
}else if(arr[left] > num) {
swap(arr,--more,left);
}else {
left++;
}
}
swap(arr,more,right);
return left;
}
//交换元素
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
//打印数组,测试用。
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
//比较数组,测试用。
public static void Compare(int[] a1, int[] a2) {
if(Arrays.equals(a1, a2)) {
System.out.println("Nice!");
}else {
System.out.println("Fucking Fucked!");
}
}
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
int[] res1 = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
res1[i] = ran;
}
Arrays.sort(res1);
quickSort(res);
Compare(res, res1);
}
}
3、随机快排
随机快排的时间复杂度远远优于经典快排,因为它所筛选的标志时随机的,在概率上求期望,时间复杂度能到达O(nlogn)
package niuke2;
import java.util.Arrays;
public class QuickSortrandom {
public static void quickSort(int[] a) {
if(a.length < 2) {
return;
}
quickSort(a,0,a.length-1);
}
public static void quickSort(int[] a,int left, int right) {
if(left < right) {
int ran = (int)(Math.random() * (right - left + 1));
swap(a, left + ran,right);
int[] num = quicksort(a,left,right);
quickSort(a, left, num[0] - 1);
quickSort(a, num[1] + 1, right);
}
}
public static int[] quicksort(int[] a,int left, int right) {
int less = left -1;
int more = right;
int num = a[right];
while(left < more) {
if(a[left] < num) {
swap(a, ++less,left++);
}else if(a[left] > num) {
swap(a,--more,left);
}else {
left++;
}
}
swap(a,right,more);
return new int[] {less + 1,more};
}
//交换元素
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
//打印数组,测试用。
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
//比较数组,测试用。
public static void Compare(int[] a1, int[] a2) {
if(Arrays.equals(a1, a2)) {
System.out.println("Nice!");
}else {
System.out.println("Fucking Fucked!");
}
}
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
int[] res1 = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
res1[i] = ran;
}
Arrays.sort(res1);
quickSort(res);
Compare(res, res1);
}
}