ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

快速排序,快排的一次分解及递归完整快排

2022-09-07 01:30:09  阅读:122  来源: 互联网

标签:arr leftPoint 递归 int 快排 rightPoint 排序 public 指针


本篇讲解的是Lomuto快排的一个衍生算法,就是基准数取的是数组的第一个元素

首先是快排中的一次执行过程的理解,本次取的是最初的一次,将数组的第一个元素【4】放置到它该去的位置

 1 import java.util.Arrays;
 2 
 3 public class DemoTest {
 4     public static void main(String[] args) {
 5         int[] arr = {4, 10, 2, 4, 9, 3, 1, 7, 5, 6, 8};
 6         //int[] arr = {3, 1, 2, 4, 4, 9, 10, 7, 5, 6, 8};
 7         //int[] arr={2, 1, 3, 4, 4, 9, 10, 7, 5, 6, 8};
 8         quickSort(arr);
 9         System.out.println(Arrays.toString(arr));
10     }
11 
12     public static void quickSort(int[] arr) {
13         int flagNum = arr[0];//第一次排序的时候,需要被放到正确位置的元素
14         int leftPoint = 0;//左边的指针
15         int rightPoint = arr.length - 1;//右边的指针
16         int temp;//交换用的标量
17 
18         while (leftPoint <rightPoint) {
19 
20             //将下面的步骤进行循环,最终将所有数字形成左边比flagNum小,右边
21             //比flagNum大的情况
22             /*注意点:右边的指针要比左边的指针先启动,因为如果左边走到最后一个大于
23             flagNum的时候,rightPoint还要--,这样righPoint就会突破到小的那边
24             因为到最后还是要把flagNum换到指针最终停下的位置,所以右指针侵入到左指针
25             的区域是没事,因为交换之后也是左小右大的情况;
26             但是如果左指针先启动,那么最后就会侵入右指针的区域,结果就是进行flagNum交换
27             的时候会把一个比arr[0]大的数字交换到数组首位置,整个排序过程就失败了*/
28 
29             //右边的指针从右往左找比flagNum小的数字,找到以后停下等待
30             while (arr[rightPoint] >= flagNum && leftPoint < rightPoint) {
31                 rightPoint--;
32             }
33             //leftPoint < rightPoint为了防止,最左边是最小,或者最右边是最大的极端情况
34             // 而造成的索引越界
35             //左边的指针从左向右找比flagNum大的数字,找到以后停下等待
36             while (arr[leftPoint] <= flagNum && leftPoint < rightPoint) {
37                 //leftPoint < rightPoint 要防止右指针侵入左侧区域后,左指针在检索到
38                 //最后一个小于等于arr[0]的元素时,leftPoint++后,把右指针越过去,越过去
39                 //之后感觉还要交换指针,处理的复杂度会上升好几个难度
40                 leftPoint++;
41             }
42 
43             //找到的两个数字交换位置
44             temp = arr[rightPoint];
45             arr[rightPoint] = arr[leftPoint];
46             arr[leftPoint] = temp;
47         }
48 
49         //交换flagNum和leftPoint,这里leftPoint或者rightPoint都可以,因为此时已经重合了
50         temp=arr[0];
51         arr[0]=arr[leftPoint];
52         arr[leftPoint]=temp;
53     }
54 
55 }

 

下面是完整的快速排序算法理解,主要分析了里面各个步骤的意义

 1 import java.util.Arrays;
 2 
 3 public class DemoQuickSort {
 4     public static void main(String[] args) {
 5         int[] arr = {4, 10, 2, 4, 9, 3, 1, 7, 5, 6, 8};
 6         quickSort(arr, 0, arr.length - 1);
 7         System.out.println(Arrays.toString(arr));
 8 
 9     }
10 
11     public static void quickSort(int[] arr, int arr_left, int arr_right) {
12         int flagNum = arr[arr_left];//第一次排序的时候,需要被放到正确位置的元素
13         int leftPoint = arr_left;//左边的指针
14         int rightPoint = arr_right;//右边的指针
15         int temp;//交换用的标量
16         //if (arr_left == arr_right)
17             //这里如果只用==是无法做到趋近出口的,以本例来讲,左半部分的递归到倒数第二次的
18             //时候,左右指针的索引值都是1,此时请注意看最下面的右半部分的递归调用,rightPoint
19             // =leftPoint=1,arr_right=1,这就造成函数左边
20             //指针的索引值是2,右边指针的索引值是1,左边大于右边了,此时递归无法结束,造成
21             //栈内存溢出。
22         if (arr_left >= arr_right)
23             return;
24         while (leftPoint < rightPoint) {
25 
26             while (arr[rightPoint] >= flagNum && leftPoint < rightPoint) {
27                 rightPoint--;
28             }
29 
30             while (arr[leftPoint] <= flagNum && leftPoint < rightPoint) {
31 
32                 leftPoint++;
33             }
34             temp = arr[rightPoint];
35             arr[rightPoint] = arr[leftPoint];
36             arr[leftPoint] = temp;
37         }
38 
39 
40         temp = arr[arr_left];
41         arr[arr_left] = arr[leftPoint];
42         arr[leftPoint] = temp;
43         quickSort(arr, arr_left, leftPoint - 1);//左半部分的数组递归调用该方法
44         quickSort(arr, rightPoint + 1, arr_right);//右半部分的数组递归调用该方法
45 
46     }
47 }

 

标签:arr,leftPoint,递归,int,快排,rightPoint,排序,public,指针
来源: https://www.cnblogs.com/JSD1207ZX/p/16663903.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有