《排序算法》——希尔排序,桶式排序(Java)

简介: 一:希尔排序        也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。        希尔排序是非稳定排序算法,先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。

一:希尔排序

       也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。

       希尔排序是非稳定排序算法,先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中,先在各组内进行直接插入排序

      然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量
=1(
<
…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

      该方法实质上是一种分组插入方法

      比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。
算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。

      一般的初次取序列的一半为增量,以后每次减半,直到增量为1。

      给定实例的shell排序的排序过程
      假设待排序文件有10个记录,其关键字分别是:
      49,38,65,97,76,13,27,49,55,04。      
      增量序列的取值依次为:
      5,2,1
           

          代码如下:
<span style="font-size:14px;">package sort;

import java.util.Arrays;

public class shellSort {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] a = {49,38,65,97,76,13,27,49,78,34,12,64,1};
		System.out.println("排序之前:");
		System.out.println(Arrays.toString(a));
		
		//希尔排序
		int len = a.length;
		while(true)
		{
			for(int i=0; i< len; i++)
				for(int j=i ; j+len < a.length; j +=len)
				{
					int temp;
					if(a[j] > a[j+len])   //大于,则交换
					{
						temp = a[j];
						a[j] = a[j+len];
						a[j+len] = temp;
					}
				}
			if(len==1)
				break;
			len--;
		}
		System.out.println("排序之后:");
		System.out.println(Arrays.toString(a));
	}

}
</span>


二:桶式排序

     该部分转载自:http://blog.csdn.net/apei830/article/details/6596057

   

       桶式排序不再是一种基于比较的排序方法,它是一种比较巧妙的排序方式,但这种排序方式需要待排序的序列满足以下两个特征:

       1:待排序列所有的值处于一个可枚举的范围之类;

       2:待排序列所在的这个可枚举的范围不应该太大,否则排序开销太大。

      排序的具体步骤如下:

     (1)对于这个可枚举范围构建一个buckets数组,用于记录“落入”每个桶中元素的个数;

    (2)将(1)中得到的buckets数组重新进行计算,按如下公式重新计算:

               buckets[i] = buckets[i] +buckets[i-1] (其中1<=i<buckets.length); 

      桶式排序是一种非常优秀的排序算法,时间效率极高,它只要通过2轮遍历:第1轮遍历待排数据,统计每个待排数据“落入”各桶中的个数,第2轮遍历buckets用于重新计算buckets中元素的值,2轮遍历后就可以得到每个待排数据在有序序列中的位置,然后将各个数据项依次放入指定位置即可。

       桶式排序的空间开销较大,它需要两个数组,第1个buckets数组用于记录“落入”各桶中元素的个数,进而保存各元素在有序序列中的位置,第2个数组用于缓存待排数据。

       桶式排序是稳定的。如果待排序数据的范围在0~k之间,那么它的时间复杂度是O(k+n)的, 桶式排序算法速度很快,因为它的时间复杂度是O(k+n),而基于交换的排序时间上限是nlg n。

      但是它的限制多,比如它只能排整形数组。而且当k较大,而数组长度n较小,即k>>n时,辅助数组C[k+1]的空间消耗较大, 当数组为整形,且k和n接近时, 可以用此方法排序。(有的文章也称这种排序算法为“计数排序”)


代码实现:

  1. public class BucketSortTest {  
  2.     public static int count = 0;  
  3.   
  4.     public static void main(String[] args) {  
  5.   
  6.         int[] data = new int[] { 536219487 };  
  7.         print(data);  
  8.         bucketSort(data, 010);  
  9.         print(data);  
  10.   
  11.     }  
  12.   
  13.     public static void bucketSort(int[] data, int min, int max) {  
  14.         // 缓存数组  
  15.         int[] tmp = new int[data.length];  
  16.         // buckets用于记录待排序元素的信息  
  17.         // buckets数组定义了max-min个桶  
  18.         int[] buckets = new int[max - min];  
  19.         // 计算每个元素在序列出现的次数  
  20.         for (int i = 0; i < data.length; i++) {  
  21.             buckets[data[i] - min]++;  
  22.         }  
  23.         // 计算“落入”各桶内的元素在有序序列中的位置  
  24.         for (int i = 1; i < max - min; i++) {  
  25.             buckets[i] = buckets[i] + buckets[i - 1];  
  26.         }  
  27.         // 将data中的元素完全复制到tmp数组中  
  28.         System.arraycopy(data, 0, tmp, 0, data.length);  
  29.         // 根据buckets数组中的信息将待排序列的各元素放入相应位置  
  30.         for (int k = data.length - 1; k >= 0; k--) {  
  31.             data[--buckets[tmp[k] - min]] = tmp[k];  
  32.         }  
  33.     }  
  34.   
  35.     public static void print(int[] data) {  
  36.         for (int i = 0; i < data.length; i++) {  
  37.             System.out.print(data[i] + "\t");  
  38.         }  
  39.         System.out.println();  
  40.     }  
  41.   
  42. }  


运行结果:

  1. 5   3   6   2   1   9   4   8   7     
  2. 1   2   3   4   5   6   7   8   9    

至此排序算法我已经总结的不少了,所谓是各有千秋吧,当然还有许多排序的算法我没有进行总结和实现(说不到哪天脑子发热了就会续着总结完吧),比如说:
外部排序(针对大文件)
间接排序(针对复杂的数据结构)
冒泡排序(最经典的也是最简单的)
计数排序
基数排序

排序算法之快速排序
排序算法之堆排序
排序算法之归并排序,插入排序
排序算法之希尔排序,桶式排序

相关文章
|
8天前
|
算法 安全 Java
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
【4月更文挑战第28天】性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
24 1
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
|
2天前
|
算法 前端开发 搜索推荐
前端算法之希尔排序
前端算法之希尔排序
4 0
|
2天前
|
搜索推荐 Java Shell
8大Java排序方法(由简入繁),有代码详解和原理指导
8大Java排序方法(由简入繁),有代码详解和原理指导
17 0
|
10天前
|
监控 搜索推荐 算法
Java排序:原理、实现与应用
【4月更文挑战第28天】本文探讨了Java中的排序算法,包括原理和实现。Java利用Comparator接口进行元素比较,通过Arrays和Collections类的sort方法对数组和列表进行排序。示例展示了使用这些方法的基本代码。此外,还讨论了冒泡排序算法和自定义排序场景,以适应不同需求。理解这些排序机制有助于提升程序效率。
11 1
|
11天前
|
搜索推荐 算法 Java
sort-06-shell sort 希尔排序算法详解
这是一个关于排序算法的系列文章摘要。文章汇总了各种排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序。特别地,希尔排序是一种改进的插入排序,通过使用不同的步长对元素进行分组排序,以提高效率。算法最终以较小的步长进行排序,接近线性时间复杂度。文章还提供了Java代码实现,并举例说明了希尔排序的过程。所有内容可在开源项目[https://github.com/houbb/sort](https://github.com/houbb/sort)中找到。
|
14天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
15天前
|
搜索推荐 算法 Java
Java实现的常用八种排序算法
提到数据结构与算法,无法避免的一点就包含排序,熟练的掌握各种排序算法则是一个程序员必备的素质之一,除此之外,排序算法也是当下各大技术公司比较喜欢问的技术点,所以,就这一点JavaBuild整理了常见的8种排序算法
6 0
|
27天前
|
人工智能 搜索推荐 Shell
【排序算法】插入排序与希尔排序,你不想知道为什么希尔比插入更快吗?
【排序算法】插入排序与希尔排序,你不想知道为什么希尔比插入更快吗?
|
29天前
|
搜索推荐 算法 Shell
【数据结构与算法】直接插入排序和希尔排序
【数据结构与算法】直接插入排序和希尔排序
|
29天前
|
算法 安全 Java
java代码 实现AES_CMAC 算法测试
该代码实现了一个AES-CMAC算法的简单测试,使用Bouncy Castle作为安全提供者。静态变量K定义了固定密钥。`Aes_Cmac`函数接受密钥和消息,返回AES-CMAC生成的MAC值。在`main`方法中,程序对给定的消息进行AES-CMAC加密,然后模拟接收ECU的加密结果并进行比较。如果两者匹配,输出&quot;验证成功&quot;,否则输出&quot;验证失败&quot;。辅助方法包括将字节转为16进制字符串和将16进制字符串转为字节。