《排序算法》——希尔排序,桶式排序(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    

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

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

相关文章
|
15天前
|
存储 算法 安全
探究‘公司禁用 U 盘’背后的哈希表算法与 Java 实现
在数字化办公时代,信息安全至关重要。许多公司采取“禁用U盘”策略,利用哈希表算法高效管理外接设备的接入权限。哈希表通过哈希函数将设备标识映射到数组索引,快速判断U盘是否授权。例如,公司预先将允许的U盘标识存入哈希表,新设备接入时迅速验证,未授权则禁止传输并报警。这有效防止恶意软件和数据泄露,保障企业信息安全。 代码示例展示了如何用Java实现简单的哈希表,模拟公司U盘管控场景。哈希表不仅用于设备管理,还在文件索引、用户权限等多方面助力信息安全防线的构建,为企业数字化进程保驾护航。
|
3月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
112 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
14天前
|
Java 程序员
Java 排序神器:Comparable 和 Comparator 该怎么选?
嗨,大家好,我是小米!今天和大家聊一聊Java社招面试中常考的经典问题——Comparable和Comparator的区别。Comparable定义对象的自然排序,适用于单一固定的排序规则;Comparator则是策略接口,用于定义自定义排序规则,适用于多样化或多变的排序需求。掌握这两者的区别是理解Java排序机制的基础,也是面试中的加分题。结合实际项目场景深入探讨它们的应用,能更好地打动面试官。如果你觉得有帮助,欢迎点赞、收藏、分享,期待你的一键三连!我们下期见~ 我是小米,一个喜欢分享技术的程序员,关注我的微信公众号“软件求生”,获取更多技术干货!
42 20
|
3月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
67 1
|
3月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
38 1
|
3月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
125 2
|
5月前
|
存储 Java
Java中ArrayList 元素的排序
本文提供了Java中根据`ArrayList`元素的某个属性进行排序的示例代码,包括实现`Comparable`接口和重载`compareTo`方法,然后使用`Collections.sort`方法进行排序。
|
5月前
|
存储 Java API
【Java高手必备】揭秘!如何优雅地对List进行排序?掌握这几种技巧,让你的代码瞬间高大上!
【8月更文挑战第23天】本文深入探讨了Java中对List集合进行排序的各种方法,包括使用Collections.sort()、自定义Comparator以及Java 8的Stream API。通过示例代码展示了不同情况下如何选择合适的方法:从简单的整数排序到自定义类对象的排序,再到利用Comparator指定特殊排序规则,最后介绍了Stream API在排序操作中的简洁应用。理解这些技术的区别与应用场景有助于提高编程效率。
171 4
|
5月前
|
搜索推荐 算法 Java
堆排序实战:轻松实现高效排序,附详细Java代码
嗨,大家好!我是小米,一名热爱技术分享的程序员。今天要带大家了解堆排序——一种基于二叉堆的数据结构,具有O(n log n)时间复杂度的选择排序算法。堆排序分为构建大顶堆和排序两个阶段:先建堆使根节点为最大值,再通过交换根节点与末尾节点并调整堆来逐步排序。它稳定高效,空间复杂度仅O(1),适合对稳定性要求高的场合。虽然不如快速排序快,但在避免递归和节省空间方面有优势。一起动手实现吧!如果有任何疑问,欢迎留言交流!
111 2
|
5月前
|
存储 Java

热门文章

最新文章