java快速排序
来源:互联网 发布:编程一小时网站登录 编辑:程序博客网 时间:2024/06/14 04:13
这里主要是参考网上的博客做的学习笔记,有不对之处请指正,其实本人现在对于快速排序还是不够清晰。
/** * <p> * <code>Test</code> * </p> * Description: * * @author Mcchu * @date 2017/12/5 15:57 */public class Test { /** * 快速排序轮次计数器1 */ private static int quickSortCount1 = 0; /** * 快速排序轮次计数器2 */ private static int quickSortCount2 = 0; /** * 快速排序 * 参考:百度百科 * * 快排简述-分治法 * 1.先从数列中取出一个数作为基准数。 * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 * 3.再对左右区间重复第二步,直到各区间只有一个数。 * * 程序解释 * 1. 设置两个变量i、j,排序开始的时候:i=0,j=N-1; * 2. 以第一个数组元素作为关键数据,赋值给key,即key=A[0]; * 3. 从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换; * 4. 从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换; * 5. 重复第3、4步,直到i=j; * (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。 * 找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。 * * 注意:快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。 * 快速排序时间复杂度:O (nlogn) * @param arr 排序数据 * @param low 每次排序时第一个数字的下标 * @param high 每次排序时最后一个数字的下标 */ private static void quickSort1(int[] arr,int low,int high){ if ( low < high ){ int i = low; // 左指针(以下标为计数),由右向左移动 int j = high; // 右指针(以下标为计数),由左向右移动 int k = arr[low]; // k为基准数 quickSortCount1++; System.out.println("第"+ quickSortCount1 +"轮次"); System.out.println("指针i指向:arr["+i+"]"); System.out.println("指针j指向:arr["+j+"]"); System.out.println("基准数k值:"+k); while( i < j ){ // 从右向左找第一个小于基准数的数 while ( i < j && k <= arr[j] ) j--; // 执行i和j交换 if ( i < j ){ int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; i++; } // 从左向右找第一个大于基准数的数 while ( i < j && k >= arr[i] ) i++; // 执行i和j交换 if ( i < j ){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; j--; } } System.out.print("排序后数组:"); for ( int in: arr ){ System.out.print(in); System.out.print(","); } System.out.println(); if(i>low) quickSort1(arr,low,i-1); if(j<high) quickSort1(arr,j+1,high); } } /** * 快速排序 * 挖坑填数+分治法 * 参考:CSDN(http://blog.csdn.net/morewindows/article/details/6684558) * * 1. 以一个数组作为示例,取区间第一个数为基准数 * 2. 初始时,i = 0; j = arr.length-1; k = a[0] (k为基准数) * 3. 可以理解为:首先在 a[0] 上挖了一个坑 * 4. 从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于k的值a[j],将a[j]挖出填到a[0], * 第一个坑就被填上了,需再找一个数字填a[j]的坑,该轮到i找了(即i++) * 5. 从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于k的值a[i],将a[i]挖出填到刚刚的a[j], * 继续找j(即j--) * * @param arr 排序数据 * @param low 每次排序时第一个数字的下标 * @param high 每次排序时最后一个数字的下标 */ private static void quickSort2( int[] arr, int low, int high ){ if (low < high) { int i = low; int j = high; int k = arr[low]; quickSortCount2++; System.out.println("第"+ quickSortCount2 +"轮次"); System.out.println("指针i指向:arr["+i+"]"); System.out.println("指针j指向:arr["+j+"]"); System.out.println("基准数k值:"+k); while (i < j) { while(i < j && arr[j] >= k) // 从右向左找第一个小于k的数 j--; if(i < j) arr[i++] = arr[j]; while(i < j && arr[i] < k) // 从左向右找第一个大于等于k的数 i++; if(i < j) arr[j--] = arr[i]; } arr[i] = k; System.out.print("排序后数组:"); for ( int in: arr ){ System.out.print(in); System.out.print(","); } System.out.println(); quickSort2(arr, low, i - 1); // 递归调用 quickSort2(arr, i + 1, high); } } private static int[] arr = {8,2,5,4,6,9,1,3,7}; /** * 快速排序 * 参考:《啊哈算法》 * 参考:CSDN (http://blog.csdn.net/binyao02123202/article/details/20051391) * * 1. j指针一步一步向左移动,找到一个小于k的值后,停下,此时j指向a[j] * 2. i指针开始一步一步向右移动,找到一个大于k的值后,停下,此时i指向a[i] * 3. 交换a[i]和a[j]的值 * 4. 再次轮到j行动,重复上面的步骤,直到i和j相遇 * 5. i和j相遇后的动作是: * 第一个值(起始值)赋值为此时他们相遇指向的那个值; * 而他们指向的那个值赋值为k * 6. 重复上面的步骤 * * @param low 每次排序时第一个数字的下标 * @param high 每次排序时最后一个数字的下标 */ private static void quickSort3( int low,int high ){ if ( low<high ){ int i = low; int j = high; int k = arr[low]; while ( i!=j ){ while ( arr[j]>=k && i<j ) j--; while ( arr[i]<=k && i<j ) i++; if ( i<j ){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } arr[low] = arr[i]; arr[i] = k; quickSort3(low,i-1); quickSort3(i+1,high); } } public static void main(String[] args) { // 测试快速排序1 int[] arr1 = {8,2,5,4,6,9,1,3,7}; int low1 = 0; int high1 = arr1.length-1; quickSort1(arr1,low1,high1); System.out.println("\n\n---------我是分割线-----------\n\n"); // 测试快速排序2 int[] arr2 = {8,2,5,4,6,9,1,3,7}; int low2 = 0; int high2 = arr2.length-1; quickSort2(arr2,low2,high2); System.out.println("\n\n---------我是分割线-----------\n\n"); // 测试快速排序3 quickSort3(0,arr.length-1); System.out.print("排序后数组:"); for ( int in: arr ){ System.out.print(in); System.out.print(","); } System.out.println(); }}
输出:
第1轮次指针i指向:arr[0]指针j指向:arr[8]基准数k值:8排序后数组:7,2,5,4,6,3,1,8,9,第2轮次指针i指向:arr[0]指针j指向:arr[6]基准数k值:7排序后数组:1,2,5,4,6,3,7,8,9,第3轮次指针i指向:arr[0]指针j指向:arr[5]基准数k值:1排序后数组:1,2,5,4,6,3,7,8,9,第4轮次指针i指向:arr[1]指针j指向:arr[5]基准数k值:2排序后数组:1,2,5,4,6,3,7,8,9,第5轮次指针i指向:arr[2]指针j指向:arr[5]基准数k值:5排序后数组:1,2,3,4,5,6,7,8,9,第6轮次指针i指向:arr[2]指针j指向:arr[3]基准数k值:3排序后数组:1,2,3,4,5,6,7,8,9,---------我是分割线-----------第1轮次指针i指向:arr[0]指针j指向:arr[8]基准数k值:8排序后数组:7,2,5,4,6,3,1,8,9,第2轮次指针i指向:arr[0]指针j指向:arr[6]基准数k值:7排序后数组:1,2,5,4,6,3,7,8,9,第3轮次指针i指向:arr[0]指针j指向:arr[5]基准数k值:1排序后数组:1,2,5,4,6,3,7,8,9,第4轮次指针i指向:arr[1]指针j指向:arr[5]基准数k值:2排序后数组:1,2,5,4,6,3,7,8,9,第5轮次指针i指向:arr[2]指针j指向:arr[5]基准数k值:5排序后数组:1,2,3,4,5,6,7,8,9,第6轮次指针i指向:arr[2]指针j指向:arr[3]基准数k值:3排序后数组:1,2,3,4,5,6,7,8,9,---------我是分割线-----------排序后数组:1,2,3,4,5,6,7,8,9,
附一个挖坑填数的草图(就是上面第二个测试的):
阅读全文
0 0
- 排序-快速排序-Java
- java排序之快速排序
- Java排序算法 快速排序
- 快速排序(java排序)
- java 快速排序,冒泡排序
- 算法:排序----Java快速排序
- 【交换排序】快速排序--Java
- java 插入排序+快速排序
- Java 排序之 快速排序
- java排序之快速排序
- Java排序算法:快速排序
- Java排序-快速排序
- Java排序算法:快速排序
- Java排序算法--》快速排序
- JAVA排序算法---快速排序
- Java 快速排序 归并排序
- Java排序算法--快速排序
- java 冒泡排序、快速排序
- 5. 编码器与PID控制
- IntelliJ IDEA For Mac 快捷键
- Java画面精美的简易聊天室
- Wireless Network poj 2236
- word2vec
- java快速排序
- 6. PIBOT的通讯协议
- MySQL基础(二)数据库、表的创建及操作
- 搭建调试符号服务器
- JavaScript基础总结
- 一道简单而经典的二分,借用一点挑战上的方法
- php 数据库连接代码
- Six Degrees of Cowvin Bacon poj 2139
- 如何比较不同浏览器的页面加载时间