快速排序

一---基本思想

先给定一个数组{-3,2,0,5,-4,1},设定一个标杆,假设就是中间值0,然后一头一尾两个指针,去对数组进行重新排序,排序的结果为中间值0的左边的数全部小于0,而标杆0的右边的数全部大于0。此时数组为{-3,-4,0,5,2,1}。然后再用相同的思想对0左边的数进行递归得{-4,-3,0,5,2,1},对0右边的数进行递归得{-4,-3,0,1,2,5}。

二---图解

 

三---代码

复制代码
 1 public class QuickSort {
 2     public static void main(String[] args) {
 3         int[] arr = {-3,2,0,5,-4,1};
 4         quickSort(arr, 0, arr.length - 1);
 5         System.out.println(Arrays.toString(arr));
 6     }
 7     public static void quickSort(int[] arr, int left, int right) {
 8        int l = left;
 9        int r = right;
10         int temp = 0;
11        int pivot = arr[(left + right) / 2];
12        while(l < r) { // 只要l < r,说明还没有排完
13            while(arr[l] < pivot) { // 找出左边大于等于pivot的数
14                l++;
15            }
16            while(arr[r] > pivot) { // 找出右边小于等于pivot的数
17                r--;
18            }
19            // 如果l == r,说明左边的数都是小于中轴值,右边的数都是大于中轴值,无需交换,退出。
20            if(l == r) {
21                break;
22            }
23            // 如果上面的语句没有执行,说明左边有比中轴值小的,右边有比中轴值大的,交换。
24            temp = arr[l];
25            arr[l] = arr[r];
26            arr[r] = temp;
27           
28        }
29         // 上面循环完成,代表我们已经按照中轴值左边全是小于等于中轴值,右边全是大于等于中轴值的规则排序好了
30         // 首先判断上面排序完成后l和r是否相等,如果相等,要错开,否则会进行栈溢出
31         if(l == r) {
32             l++;
33             r--;
34         }
35         // 左边递归排序
36         if(left < r) { // 错开之后r是在左边的,所以这里就是r。
37             quickSort(arr, left, r);
38         }
39         // 左边部分排好了,接下来进行右边
40         if(right > l) { // 错开之后l是在左边的,所以这里就是l。
41             quickSort(arr, l, right);
42         }
43     }
复制代码

 

四---出现问题

上面的代码其实是有瑕疵的,思考这样一个数组

{-4,2,0,0,7}  

程序报错:

 

改进代码,红色部分即为优化。

复制代码
 1 public static void quickSort(int[] arr, int left, int right) {
 2        int l = left;
 3        int r = right;
 4         int temp = 0;
 5        int pivot = arr[(left + right) / 2];
 6        while(l < r) { // 只要l < r,说明还没有排完
 7            while(arr[l] < pivot) { // 找出左边大于等于pivot的数
 8                l++;
 9            }
10            while(arr[r] > pivot) { // 找出右边小于等于pivot的数
11                r--;
12            }
13            // 如果l == r,说明左边的数都是小于中轴值,右边的数都是大于中轴值,无需交换,退出。
14            if(l == r) {
15                break;
16            }
17            // 如果上面的语句没有执行,说明左边有比中轴值小的,右边有比中轴值大的,交换。
18            temp = arr[l];
19            arr[l] = arr[r];
20            arr[r] = temp;
21            // 交换完成,现在判断左边或右边的数是否和中轴值相同,如果相同,要进行前进或者后退,防止进入死循环。
22            if(arr[l] == pivot) {
23                r--;
24            }
25            if(arr[r] == pivot) {
26                l++;
27            }
28 
29        }
30         // 上面循环完成,代表我们已经按照中轴值左边全是小于等于中轴值,右边全是大于等于中轴值的规则排序好了
31         // 首先判断上面排序完成后l和r是否相等,如果相等,要错开,否则会进行栈溢出
32         if(l == r) {
33             l++;
34             r--;
35         }
36         // 左边递归排序
37         if(left < r) { // 错开之后r是在左边的,所以这里就是r。
38             quickSort(arr, left, r);
39         }
40         // 左边部分排好了,接下来进行右边
41         if(right > l) { // 错开之后l是在左边的,所以这里就是l。
42             quickSort(arr, l, right);
43         }
44     }
复制代码

 

posted on   Love&Share  阅读(75)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示