算法图解之快速排序
副标题[/!--empirenews.page--]
分而治之(又称D&C)书中举了一个例子,假设你是农场主,有一块土地,如图所示: ? 你要将这块地均匀分成方块,且分出的方块要尽可能大。 ? ? 从图上看,显然是不符合预期结果的。 (1)D&C算法是递归的; 就如何保证分出的方块是最大的呢?《算法图解》中的快速排序一章提到了欧几里得算法。 什么是欧几里得算法? 举个代码例子说一下欧几里得算法: package cn.pratice.simple; public class Euclid { static void main(String[] args) { int m = 63; int n = 18int remainer = 0while(n!=) { remainer = m % n; m = n; n = remainer; } System.out.println(m); } } ? 最终的结果是9,正好63和18的最大公因数也是9. 再举个例子说明,如图所示: ? 需要将这些数字相加,并返回结果,使用循环很容易完成这种任务,以Java为例: ? int []num = new int[] {2,4,1)">6}; int total = for (int i = 0; i < num.length; i++) { total += num[i]; } System..println(total); } } 快速排序快速排序是一种常用的排序算法,比选择排序快的多。 QuickSort { //声明静态的 getMiddle() 方法,该方法需要返回一个 int 类型的参数值,在该方法中传入 3 个参数 int getMiddle(int[] list,int low,1)">int high) { int tmp = list[low];数组的第一个值作为中轴(分界点或关键数据) while(low<high) { while(low<high && list[high]>tmp) { high--; } list[low] = list[high];比中轴小的记录移到低端 while(low<high&&list[low]<tmp) { low++; } list[high]=list[low];比中轴大的记录移到高端 } list[low] = tmp;中轴记录到尾 return low; } 创建静态的 unckSort() 方法,在该方法中判断 low 参数是否小于 high 参数,如果是则调用 getMiddle() 方法,将数组一分为二,并且调用自身的方法进行递归排序 void unckSort(if(low<int middle = getMiddle(list,low,high);将list数组一分为二 unckSort(list,middle-1);对低字表进行递归排序 unckSort(list,middle+1,1)">对高字表进行递归排序 } } 声明静态的 quick() 方法,在该方法中判断传入的数组是否为空,如果不为空,则调用 unckSort() 方法进行排序 void quick([] str) { if(str.length>) { 查看数组是否为空 unckSort(str,1)">0,str.length-1); } } 测试 main(String[] args) { int[] number = {13,1)">15,1)">24,1)">99,1)">14,1)">11,1)">3}; System.out.println("排序前:"); i : number) { System.out.print(i+" ); } quick(number); System.r排序后:); } } } 此示例来自Java数组排序:Java快速排序(Quicksort)法 没有什么比代码示例来的直接痛快。 再谈大O表示法快速排序的独特之处在于,其速度取决于选择的基准值。 常见的大O运行时间图,如下: ? 上述图表中的时间是基于每秒执行10次操作计算得到的。这些数据并不准确,这里提供它们只是想让你对这些运行时间的差别有大致认识。实际上,计算机每秒执行的操作远远不止10次。 在该节中,作者说合并排序比选择排序要快的多。合并排序,用数学公式表示为O(n log n),而选择排序为O(n的2次方)。 package cn.pratice.simple; import java.util.Arrays; MergeSort { private void mergeSort([] original) { if (original == nullthrow new NullPointerException(The array can not be null !!!); } int length = original.length; if (length > int middle = length / 2; int partitionA[] = Arrays.copyOfRange(original,middle); 拆分问题规模 int partitionB[] = Arrays.copyOfRange(original,middle,length); 递归调用 mergeSort(partitionA); mergeSort(partitionB); sort(partitionA,partitionB,original); } } void sort(int[] partitionA,1)">int[] partitionB,1)">int j = int k = while (i < partitionA.length && j < partitionB.length) { if (partitionA[i] <= partitionB[j]) { original[k] = partitionA[i]; i++; } else { original[k] = partitionB[j]; j++; } k++; } if (i == partitionA.length) { while (k < original.length) { original[k] = partitionB[j]; k++; j++; } } else if (j == partitionA[i]; k++; i++; } } } void print([] array) { if (array == ); } StringBuilder sb = new StringBuilder([ element : array) { sb.append(element + ,); } sb.replace(sb.length() - ]); System..println(sb.toString()); } long startTime = System.currentTimeMillis(); 获取开始时间 int original[] = int[] { }; 0; i < original.length; i++) { System.out.print(original[i]+); } mergeSort(original); print(original); long endTime = System.currentTimeMillis(); 获取结束时间 System.程序运行时间:" + (endTime - startTime) + ms"); 输出程序运行时间 } } 此示例来自 比较快速排序与合并排序(编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |