算法——快速排序迭代式和递归式的Java实现
Posted 乌池鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法——快速排序迭代式和递归式的Java实现相关的知识,希望对你有一定的参考价值。
快速排序迭代式和递归式的Java实现
快速排序基于分治法的思想,在待排序表中任选一值作为中枢值 pivot,一趟快排将所有大于该值的元素置于一边,小于该值的元素置于另一边,这样一个元素在排序中的最终位置就已确定。接下来将中枢值左右两边的区域分别进行下一趟快排,直到所有的元素都有序排列。
空间效率:最好情况为 O(log2(n+1))
,最坏情况为 O(n)
,平均空间复杂度 O(log2(n))
。
时间效率:最好情况为 O(n*log2(n))
,最坏情况 O(n^2)
,平均时间复杂度 O(n*log2(n))。
快速排序是所有内部排序中平均性能最优的算法,同时也是一个不稳定的排序算法。
递归式
1 public class Test {
2
3 public static void main(String[] args) {
4
5 int[] nums = {2, 12, 32, 32, 43, 5, 74, 13, 87, 12, 44, 2, 41, 5, 33};
6
7 recursiveQuicksort(nums,0,nums.length-1);
8
9 System.out.println("Sorted array : " + Arrays.toString(nums));
10
11 }
12
13 //recursiveQuicksort(int[] 被排序数组, int 数组下界, int 数组上界)
14 private static void recursiveQuicksort(int[] nums, int low, int high) {
15
16 if(low < high){
17
18 int pivotpos = partition(nums, low, high);
19
20 recursiveQuicksort(nums, low, pivotpos -1);
21 recursiveQuicksort(nums, pivotpos + 1, high);
22
23 }
24 }
25
26 private static int partition(int[] nums, int low, int high) {
27
28 //将当前列表中第一个元素设为中枢值
29 int pivot = nums[low];
30
31 while(low < high){
32
33 //找到第一个小于中枢值的数,置于low的位置
34 while(low < high && nums[high] >= pivot){
35 --high;
36 }
37 nums[low] = nums[high];
38
39 //找到第一个大于中枢值的数,置于high的位置
40 while(low < high && nums[low] <= pivot){
41 ++low;
42 }
43 nums[high] = nums[low];
44 }
45
46 //这样一趟下来nums[low]左端都是小于中枢值的数,右端都是大于中枢值的数,一个元素的最终排序位置确定
47 nums[low] = pivot;
48
49 return low;
50 }
51 }
1 public class Test {
2
3 public static void main(String[] args) {
4
5 int[] nums = {34, 32, 43, 12, 11, 32, 22, 21, 32};
6
7 System.out.println("Unsorted array : " + Arrays.toString(nums));
8
9 iterativeQuicksort(nums);
10
11 System.out.println("Sorted array : " + Arrays.toString(nums));
12
13 }
14
15 public static void iterativeQuicksort(int[] nums) {
16
17 //新建栈,模拟递归操作
18 Stack stack = new Stack();
19
20 stack.push(0);
21 stack.push(nums.length);
22
23 while (!stack.isEmpty()) {
24 int high = (int)stack.pop();
25 int low = (int)stack.pop();
26
27 if (high - low < 2) {
28 continue;
29 }
30
31 //pivot为low与high的平均值,保证随机性,降低抽到数组中最小值或最大值的概率
32 int p = low + ((high - low) / 2); //pivot为low与high的平均值,这样写防止溢出
33
34 //经过一趟partition后,p所在的位置已是排序后的最终位置
35 p = partition(nums, p, low, high);
36
37 stack.push(p + 1);
38 stack.push(high);
39
40 stack.push(low);
41 stack.push(p);
42 }
43 }
44
45 private static int partition(int[] input, int position, int start, int end) {
46
47 int l = start;
48 int h = end - 2;
49
50 int pivot = input[position];
51
52 //将pivot换至最右端
53 swap(input, position, end - 1);
54
55 //筛选pivot的最终位置
56 while (l < h) {
57 if (input[l] < pivot) {
58 l++;
59 } else if (input[h] >= pivot) {
60 h--;
61 } else {
62 swap(input, l, h);
63 }
64 }
65 //pos为pivot的最终位置
66 int pos = h;
67
68 //如果pivot左边的数都小于它,说明它本来就应该在最右端的位置,因此pos++
69 if (input[h] < pivot) {
70 pos++;
71 }
72 swap(input, end - 1, pos);
73
74 return pos;
75 }
76
77 private static void swap(int[] arr, int i, int j) {
78 int temp = arr[i];
79 arr[i] = arr[j];
80 arr[j] = temp;
81 }
82 }
递归与迭代
-
优点:
-
极大的减少了代码量,代码简单易读
-
将大问题转化成小问题,逻辑清晰
-
-
缺点:
-
递归不断调用函数,不断压栈,浪费空间容易造成栈溢出
-
频繁的入栈出栈操作也会导致性能损失
-
迭代:函数内某段代码实现循环,不断把变量的原值推导成新值,直到最终结果产生
-
优点:
-
效率比递归高,运行时间只随循环的增加而增加
-
不需要反复调用从而占用栈的空间
-
-
缺点:
-
代码复杂,较难理解
-
面对复杂问题时,难以构思代码
-
以上是关于算法——快速排序迭代式和递归式的Java实现的主要内容,如果未能解决你的问题,请参考以下文章