我是靠谱客的博主 舒服豌豆,这篇文章主要介绍八大基本排序---快速排序(经典快排、随机快排)(荷兰国旗问题),现在分享给大家,希望可以做个参考。

引言:

clip_image002_thumb[1]

解答:

clip_image004_thumb[1]

需要准备3个下标

clip_image006_thumb[1]

如果当前数字=num,cur跳下一个

clip_image008_thumb[1]

如果数组中的当前数字<num,把这个数(3)和小于区域的下一个数(5)交换

clip_image010_thumb[1]

然后小于区域扩一下

clip_image012_thumb[1]

然后cur跳下一个位置

clip_image014_thumb[1]

数组中的当前数字<num,把这个数(2)和小于区域的下一个数(5)交换,

然后小于区域扩一下

然后cur跳下一个位置

clip_image016_thumb[1]

PS:

如果一上来遇到的就是cur<num

把这个数(3)和小于等于区域的下一个数(3)交换【自己和自己交换】

clip_image018_thumb[1]

数组中的当前数字>num,把这个数(7)和大于区域的前一个数(x)交换

然后大于区域向左扩一个位置,more移动一下

然后让cur停留在原地,继续考察换过来的x跟num的大小关系

clip_image020_thumb[1]

当cur == more的时候,整个过程停止

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Code_08_NetherlandsFlag { public static int[] partition(int[] arr, int L, int R, int num) { int less = L - 1; int more = R + 1; while (L < more) { if (arr[L] < num) { swap(arr, ++less, L++); } else if (arr[L] > num) { swap(arr, --more, L); } else { L++; } } //less + 1:等于区域的第一个位置,more - 1:等于区域的最后 一个位置 return new int[] { less + 1, more - 1 }; } // for test public static void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } }

传统快排:与荷兰国旗问题类似

image_thumb[1]

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.Arrays; //利用荷兰国旗问题进行快排 public class QuickSort { public static void main(String[] args) { int[] arr = {3,1,4,5,2,2,0,13}; System.out.println(Arrays.toString(arr)); // int[] res = new int[2]; // res = partition(arr, 0, arr.length-1); // System.out.println(res[0]+" " +res[1]); // System.out.println(Arrays.toString(arr)); quickSort(arr, 0, arr.length-1); System.out.println(Arrays.toString(arr)); } public static void quickSort(int[] arr,int L,int R){ if (L>=R) { return; } int[] p = partition(arr, L, R); quickSort(arr, L, p[0]-1); quickSort(arr, p[1]+1, R); } //以数组的最后一个数字arr[R]作为num //返回等于区域的下标 public static int[] partition(int[] arr,int L ,int R){ int less = L-1; int more = R+1; int num = arr[R]; while (L < more) { if (arr[L]==num) { L++; }else if (arr[L]<num) { swap(arr,++less,L++); }else if (arr[L]>num) { swap(arr,L ,--more ); } } int[] res = {less+1,more-1}; return res; } public static void swap(int[] arr, int i, int j ){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }

 

经典快排存在的问题:

如果是一个有序的数组,算法的时间复杂度是O(N^2)

如果所选的num刚好把数组平分为左:<num;右>num,算法的时间复杂度是O(N*logN)

clip_image002[5]_thumb

一次只搞定了7这一个数字

下一次在<7的区间里,只搞定了6,划分为<6的区域和=6的区域

每一次都是一次O(N),所以总的是O(N^2)

或者

clip_image004[5]_thumb[3]

clip_image006[5]_thumb[1]

解决方法:随机快排

随机找到一个数,把这个数和最后一个数字交换,进行快排

clip_image008[5]_thumb[1]

clip_image010[5]_thumb[1]

这样最差情况就是在某个概率的情况下出现的,此时时间复杂度就是一个概率事件

此时时间复杂度的长期期望:O(N*logN)

快排的额外空间复杂度:O(logN)

空间用在记录划分点

clip_image012[5]_thumb[1]

clip_image014[5]_thumb[1]

转载于:https://www.cnblogs.com/yuange678/p/10819720.html

最后

以上就是舒服豌豆最近收集整理的关于八大基本排序---快速排序(经典快排、随机快排)(荷兰国旗问题)的全部内容,更多相关八大基本排序---快速排序(经典快排、随机快排)(荷兰国旗问题)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部