您的位置:首页 > 编程语言 > Java开发

java 交换排序之(冒泡排序、快速排序)

2016-02-26 14:28 666 查看
2016年上班第一天,闲来无事,先写篇博文来结束今天。我们大家都知道java的排序算法很多,接下来我就先看看java最常用的几种排序算法的思想源码附上。(本文所有排序只针对值排序,关于对象排序问题待续.....)1.插入排序(直接插入排序、二分法插入排序、表插入排序、shell排序)2.选择排序(直接选择排序、堆排序)3.交换排序(冒泡排序、快速排序)4.分配排序(基数排序)5.归并排序(内排序、外排序)一、java冒泡排序实现(大家最喜欢也是最简单的排序算法,但是性能不是那么ok 当排序数组很大是性能就很低了)冒泡排序算法实现思想://算法分析:一次比较相邻的两个数,将大数放在前面、小数放在后面(小数放在前面、大数放在后面)。首先比较第一个和第二 个,满足条件互换位置。然后第二个和第三个比较。直到倒数第二个和最后一个比较。得到一个最大或者最小的数放 在最后完成第一轮比较。一次进行第二轮比较、第三轮直到结束。//冒泡排序算法:(实现源码)public static void maopaoSort(int[] arr){int temp;for(int i = 0;i < arr.length; i++){for(int j = 0; j < arr.length-1-i; j++ ){if(arr[j] < arr[j+1]){temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}二、java交换排序之快速排序//算法分析:快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。(1) 分治法的基本思想 分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。(2) 实例分解快速排序是对冒泡排序的一种该进(两种排序都是属于交换排序),通过一趟排序将原有的排序数组分成独立的两个部分。其中一部分的数据比另外一部分的数据都要小。然后再按照此方法对刚划分的两部分进行同样的分割。以此达到整个数组变成有序的序列。假设需要排序的数组是A[0]......A[N-1],首先任意选取一个数据(通常选择A[0])作为关键数据然后把所有比它小的数都放在前面,所有比它大的数都放在它后面。这整个过程称为一趟快速排序(因此我们可以把一趟快速排序写成一个独立的方法。方便重复调用)(1)设置两个变量i,j,排序开始的时候i=0,j=N-1.(2)以第一个数据A[0]作为关键数据,赋值给key,即key=A[i]。(3)从j(j = j-1 )开始向前搜索,找到第一个小于key的值,让该值与key进行交换。(4)从i(i = i+1)开始向后搜索,找到第一个大于key的值,让该值与key交换。(5)重复(3)、(4)不,直到i=j。列如:需要排序的数组A=[49,38,65,97,76,13,27]初始关键数据为A[0]=49,经过第一趟快速排序后所有比49小的放在了49 的前边,比49大的都放在了49的后边。因此经过第一趟排序后的A=[27, 38, 13, 49, 76, 97, 65]记录关机数据在经过第一轮快速排序后的位置i=3,因此A数组被分为A1=[27, 38, 13]、A0=[49]、A2=[76, 97, 65]三个部分。package cn.bsxy;/*** 快速排序实现源码* @author smartluobo**/public class QuickSort {/**** @a a需要进行排序的数组* @i i排序的其实位置关键数据的在数组中的位置,第一次调用i = 0* @j j需要进行排序终止位置。第一次调用是j=a.length-1* @return 返回经过一趟快速排序后关键数据的位置*/public int partition(int[] a, int i, int j){//根据关键数据分割需要排序的数组并返回关键数据在分割后的位置int key = a[i];//临时变量用于存储关键数据while(i < j){while(i < j && a[j] >= key)//找出第一个比key小的数执行j--并将其赋值给a[i]j--;//执行j = j-1操作a[i] = a[j];//将a[j]的值赋值给a[i]while(i < j && a[i] <= key)//找出第一个比key大的数执行i++并将其赋值给a[j]i++;//执行i = i+1a[j] = a[i];//把该值赋值给a[j]}a[i]=key;//完成一趟快速排序后将选择的关键数据放在分割点上return i;//返回关键数据在经过一趟快速排序后的位置}public void sort(int[] a, int i, int j){if(i < j){int n = partition(a ,i ,j);//记录返回的关键数据在经过一趟快速排序后的位置sort(a,i,n-1);//对左边部分进行递归调用。依次完成分割sort(a,n+1,j);//对右边部分进行递归调用。依次完成分割}}public static void main(String[] args) {int[] a = {49,38,65,97,76,13,27};new QuickSort().sort(a, 0, a.length-1);for (int i : a) {System.out.print(i+"\t");}}}三、性能测试package cn.bsxy;import java.util.Random;/**** @author smartluobo* 测试java交换排序的冒泡排序和快速排序两种方法的性能*/public class SortTest {/*** 完成一趟快速排序* @param a 需要排序的数组* @param i 起始位置,第一次为0* @param j 结束位置,一般为数组的长度-1 a.length-1* @return*/public int partition(int[] a,int i,int j){int key = a[i];while(i < j){while(i < j && a[j] <= key)j--;a[i] = a[j];while(i < j && a[i] >= key)i++;a[j] = a[i];}a[i] = key;return i;}/*** 快速排序方法实现。递归调用该方法完成数组的排序* @param a* @param i* @param j*/public void sort(int[] a, int i, int j){if(i < j){int n = partition(a,i,j);sort(a,i,n-1);sort(a,n+1,j);}}/*** 冒泡排序方法实现* @param a 需要排序的数组*/public static void maopaoSort(int[] a){int temp;for(int i = 0; i< a.length;i++){for(int j = 0;j<a.length-i-1;j++){if(a[j] < a[j+1]){temp = a[j];a[j] = a[j+1];a[j+1] = temp;}}}}/*** 创建一个长度很长的无序数组* @return*/public static int[] createRandom(){int[] a = new int[18000];Random random = new Random();int b;for(int i = 0;i < a.length;i++){b = random.nextInt(100000);a[i] = b;}return a;}public static void main(String[] args) {int[] a = createRandom();int[] b = a;//将a数组赋值给b是为了保证两个排序方法对完全一样的两个数组进行排序long maopaoStart = System.currentTimeMillis();maopaoSort(b);//使用冒泡排序法对生成的数组进行排序long maopaoEnd = System.currentTimeMillis();System.out.println("maopaoStart:"+maopaoStart+", maopaoEnd"+maopaoEnd+"快速排序法用 时:"+(maopaoEnd-maopaoStart));long start = System.currentTimeMillis();new SortTest().sort(a, 0, a.length-1);//使用快速排序方法对生成的数组排序long end = System.currentTimeMillis();System.out.println("start:"+start+", end"+end+"快速排序法用时:"+(end-start));// int k = 0;// for (int i : a) {// k++;// System.out.print(i+"\t");// if(k%100 == 0){// System.out.println();// }// }// 经打印测试冒泡排序和快速排序都能正常排序需要排序的数组}}运行以上代码打印台输出为:maopaoStart:1456461874561, maopaoEnd:1456461874976 快速排序法用时:415start:1456461874977, end:1456461875059 快速排序法用时:82经过多次测试后发现快速排序的速度比冒泡排序快 4~5倍。缺点是快速排序使用递归调用,当数组的长度足够大时,会出现内存溢出的情况.....具体解决方案还望各位大神给出宝贵意见.

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: