测试排序的效率,为什么:希尔排序>归并排序>快速排序?

问题描述

我看看几篇排序的算法的文章,大家都说效率一般都是:快速排序>归并排序>希尔排序然后就用java自己动手测了一下,测试结果却是:希尔排序>归并排序>快速排序而且当数据量过大时,归并排序 和 快速排序 会出现栈溢出. 以下是我写的源代码,请帮我分析一下是什么原因? package com.test;import java.util.Arrays;import java.util.Random;public class Sort {public static void main(String[] args) {int[] arr = new int[400000];Random r = new Random();long start, end;init(arr, r);System.out.print("希尔排序...");start = System.currentTimeMillis();sort1(arr);end = System.currentTimeMillis();System.out.println("完成" + (end - start));//System.out.println(Arrays.toString(arr));init(arr, r);System.out.print("归并排序...");start = System.currentTimeMillis();arr = sort2(arr, 0, arr.length - 1);end = System.currentTimeMillis();System.out.println("完成" + (end - start));//System.out.println(Arrays.toString(arr));init(arr, r);System.out.print("快速排序...");start = System.currentTimeMillis();sort3(arr, 0, arr.length - 1);end = System.currentTimeMillis();System.out.println("完成" + (end - start));//System.out.println(Arrays.toString(arr));}/** * 初始化 */private static void init(int[] arr, Random r) {System.out.print("n初始化...");for (int i = 0; i < arr.length; i++) {arr[i] = r.nextInt(100);}//System.out.println("n" + Arrays.toString(arr));}/** * 希尔排序 */private static void sort1(int[] a) {int i, j, temp, increment;// increment增量缩短,当增量为1时,即把整个数组进行插入排序for (increment = a.length / 3; increment > 0; increment /= 3) {for (i = increment; i < a.length; i++) {temp = a[i];for (j = i - increment; j >= 0 && temp < a[j]; j -= increment) {a[j + increment] = a[j];}a[j + increment] = temp;}}}/** * 归并排序 * left,right参数表示:把a数组中fist--right之间的元素排序 * 排序结果以新数组返回. */private static int[] sort2(int[] a, int left, int right) {//判断递归结束条件if (right <= left) return new int[] { a[left] };//从数组中间切成左右两部分,mid为右边部分的起始下标int mid = (left + right + 1) / 2;//第一步:用递归把数组左边排序int[] a1 = sort2(a, left, mid - 1);//第二步:用递归把数组右边排序int[] a2 = sort2(a, mid, right);//第三步:归并操作,把左右两边序列合并到新的数组int[] result = new int[right - left + 1];int i = 0, j = 0, k = 0;while (i < a1.length && j < a2.length) {if (a1[i] < a2[j])result[k++] = a1[i++];elseresult[k++] = a2[j++];}while (j < a2.length) {result[k++] = a2[j++];}while (i < a1.length) {result[k++] = a1[i++];}return result;}/** * 快速排序 * left,right参数表示:把a数组中left--right之间的元素排序 */private static void sort3(int[] a, int left, int right) {// 第四步:判断结束递归的条件if(left>=right) return;// 第一步:以left为基数,把a分成左右两部分,使左边部分小于右边部分int i = left;//最终i==j;for (int b=1,j=right; i < j;) {// 最初b=1,表示以left为基数if (a[i] > a[j]) {//交换位置int temp = a[i];a[i] = a[j];a[j] = temp;if (b==1) i++; else j--;//应基数位置不同,处理也不同b = -b;//交换位置后,基数位置变化,b=1,表示以left为基数} else {if (b==1) j--; else i++;//应基数位置不同,处理也不同}}// 第二步:递归排序左部分(left到i-1)sort3(a,left,i-1);// 第三步:递归排序右部分(i+1到right)sort3(a,i+1,right);}} 运行结果如下: 初始化...希尔排序...完成40初始化...归并排序...完成53初始化...快速排序...完成1411

解决方案

排序效率根本就不能单纯的说哪种比哪种高吧,建议看看算法导论
解决方案二:
网上的文章有很多都是抄袭的,靠不住看算法的性能 通过两方面,时间复杂度、稳定性比如说快速排序的时间复杂度平均为O(nlogn) 快排不稳定归并的时间复杂度 为O(nlogn) jdk里面用的就是归并,稳定shell排序为o(n^1.25)你这里主要是在方法里new 了太多的数组,在递归的时候导致OOM具体的你可以通过维基百科上面看
解决方案三:
因为你的数据量太大40万条,当数据量很大时快速排序就不是最快的了。而且排序应该用一个数组

时间: 2024-11-04 02:23:26

测试排序的效率,为什么:希尔排序&amp;gt;归并排序&amp;gt;快速排序?的相关文章

常用内部排序算法之五:希尔排序

前言 在前面介绍常用内部排序算法的文章中,我们知道在简单排序算法中,直接插入排序算法的时间复杂度是要优于冒泡排序和简单选择排序的.而这里要讲的希尔排序则是优于直接插入排序的.而且希尔排序打破了原来简单排序中时间复杂度不能超过O(n2)的神话.这也是希尔排序伟大的地方,而且希尔排序不同于之前三种简单排序,希尔排序是以一个科学家的名字进行命名的. 希尔排序的原理 由于希尔排序是在直接插入排序的基础上进行改进的,所以为了更好理解希尔排序,需要再次将直接插入排序请出来.我们知道直接插入排序的基本思想是将

Java排序算法总结之希尔排序_java

本文实例讲述了Java排序算法总结之希尔排序.分享给大家供大家参考.具体分析如下: 前言:希尔排序(Shell Sort)是插入排序的一种.是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名.本文主要介绍希尔排序用Java是怎样实现的. 希尔排序(缩小增量法) 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序.希尔排序并不稳定,O(1)的额外空间,时间复杂度为O(N*(logN)^2).最坏的情况下的执行效率和在平均情况下的执行效率相

C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序

插入|排序|算法 本文介绍了C#的四种排序算法:冒泡排序.选择排序.插入排序和希尔排序 冒泡排序 using System: namespace BubbleSorter { public class BubbleSorter { public void Sort(int [] list) { int i,j,temp: bool done=false: j=1: while((j<list.Length)&&(!done)) { done=true: for(i=0:i<li

内部排序:插入排序和希尔排序的N种实现

前言 本来想将所有的内部排序总结为一篇博文,但是随着研究的深入,还是放弃了这个念头,斟前酌后,还是觉得分开来写比较好,具体原因,看完本篇博文也就自然明了了. 本篇文章主要探讨插入排序和希尔排序,之所将二者放在一起,很明显,是因为希尔排序是建立在插入排序的基础之上的. 注:以下各排序算法的N种实现方法大部分都是我根据算法思想,自己写出来的,或者是参考其本身的经典实现,我自己都已测试通过,但不敢保证一定都没问题,如果有疑问,欢迎指出. 插入排序 插入排序的思想很简单,它的基本操作就是将一个数据插入到

排序算法系列之希尔排序

算法排序之希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本.  基本思想    先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组内进行直接插人排序:然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<-<d2<d1),即所有记录放在同一组中进行直接插入排序为止. 希尔排序的时间性能优于直接插入排序的原因: ①当文件初态基本有序时直接插入排

Java排序算法&amp;amp;nbsp;希尔排序

希尔排序(Shell Sort)是插入排序的一种.是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名.本文主要介绍希尔排序用Java是怎样实现的. AD: 希尔排序(缩小增量法) 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序.希尔排序并不稳定,O(1)的额外空间,时间复杂度为O(N*(logN)^2).最坏的情况下的执行效率和在平均情况下的执行效率相比相差不多. 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录

经典算法(3) 希尔排序的实现

希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成 的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小) 时,再对全体元素进行一次直接插入排序.因为直接插入排序在元素基本有序的情况下(接近最好情况), 效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高. 以n=10的一个数组49, 38, 65,

内部排序算法:希尔排序

基本思想 先取一个小于n的整数d1作为第一个增量,把待排序的全部记录分成dx个组.所有距离为d1的倍数的记录放在同一个组中. 先在各组内进行直接插人排序. 然后,取第二个增量d2<d1重复上述的分组和排序. 直至所取的增量dt=1(dt<dt-x<-<d2<d1),即所有记录放在同一组中进行直接插入排序为止. 算法实现 希尔排序算法,Java实现,代码如下所示: 01 public abstract class Sorter { 02 public abstract void

我的Java开发学习之旅------&amp;gt;Java经典排序算法之希尔排序

一.希尔排序(Shell Sort) 希尔排序(Shell Sort)是一种插入排序算法,因D.L.Shell于1959年提出而得名. Shell排序又称作缩小增量排序. 二.希尔排序的基本思想 希尔排序的中心思想就是:将数据进行分组,然后对每一组数据进行排序,在每一组数据都有序之后 ,就可以对所有的分组利用插入排序进行最后一次排序.这样可以显著减少交换的次数,以达到加快排序速度的目的.       希尔排序的中心思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组.所有距