您的位置:首页 > 其它

快速排序和堆排序

2020-03-20 01:38 246 查看

快速排序思想:在partition中,首先以最右边的值作为划分值x,分别维护小于x的区间,等于x的区间,以及大于x的三个区间,最后返回划分值的左边界和右边界.时间复杂度为O(nlogn).

public class QuickSort {
public static void quickSort(int[] arr) {
if(arr == null || arr.length < 2)
return ;
sortProgress(arr, 0 , arr.length - 1);
}
public static void sortProgress(int[] arr, int L, int R) {
if(L < R) {
//随机取L到R之间的一个数与R交换.
swap(arr, L + (int)(Math.random() * (R - L + 1)), R);
//p数组的大小为2,p[0]表示划分值的左边界,p[1]表示划分值的右边界.
int[] p = partition(arr, L, R);
sortProgress(arr, L, p[0] - 1);
sortProgress(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 tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
int[] arr = new int[]{123,45,767,343,654,2,66,88};
System.out.print("原始数组:");
for(int i = 0; i < arr.length; i++)
if(i != arr.length - 1)
System.out.print(arr[i] + " ");
else
System.out.println(arr[i]);
quickSort(arr);
System.out.print("快速排序后:");
for(int i = 0; i < arr.length; i++)
if(i != arr.length)
System.out.print(arr[i] + " ");
else
System.out.println(arr[i]);
}
}

运行结果:

堆排序思想:在构建最大堆堆的过程,每次向上调整,只需和父节点进行比较,构建堆的时间复杂度为O(n),在堆排序的过程中,取堆顶元素与最后一个元素交换,然后堆顶元素向下调整,维护最大堆,最终即可完成排序.时间复杂度为O(nlogn).

public class HeapSort {
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 = 2 * index + 1;
while(left < size){
int largest = left + 1 < size && arr[left + 1] > arr[left]? left + 1: left;
largest = arr[index] > arr[largest] ? index: largest;
if(largest == index) {
break;
}
swap(arr, index, largest);
index = largest;
left = 2 * index + 1;
}
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
int[] arr = new int[] {3,66,65,43,213,76,66,23};
System.out.print("原始数组:");
for(int i = 0; i < arr.length; i++)
if(i != arr.length - 1)
System.out.print(arr[i] + " ");
else
System.out.println(arr[i]);
heapSort(arr);
System.out.print("堆排序后:");
for(int i = 0; i < arr.length; i++)
if(i != arr.length - 1)
System.out.print(arr[i] + " ");
else
System.out.println(arr[i]);
}
}

运行结果:

总结
快速排序是不稳定的。算法时间复杂度O(nlogn)
堆排序是不稳定的。算法时间复杂度O(nlogn)。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐