算法_排序_希尔排序
记得学习算法的时候还是在大二开的数据结构课程与算法课程上学的,当初对算法甚是感兴趣,当初对那些提出算法的牛人甚是崇拜。可是后面的学习中却很少用到算法,渐渐的淡忘啦。如今快毕业了,突然就想在毕业之前把自己在以前遗忘的算法好好复习一下,就买了一本Robert Sedgewick写的《算法》,这本书相对于《算法导论》个人感觉更易于理解。
感觉学完算法之后,最大的收获就是"分治"的思想。
今天要写的是希尔排序,一种基于插入排序的快速的排序算法。我们知道 插入排序 对于大规模乱序数字插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点点地从数组一段移动到另一段。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需要 N-1 次移动。希尔排序为了加快速度简单地该井了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序讲局部有序的数组排序。
希尔排序的思想就是使数组中任意间隔为h的元素都是有序的。这样的数组被称为h有序数组。换句话说,一个h有序数组就是h个互相独立的有序数组编制在一起组成的一个数组。
实现希尔排序的一种方法是对于每个h,用插入排序讲h个子数组独立的排序。但因为子数组是相互独立的,一个更简单的方法是在h子数组中将每个元素交换到比它大的元素之前(将比它大的元素向右移动一格)。只需要在插入排序的代码中将移动的元素距离由1改为h即可。这样希尔排序的实现就转化为一个类似于插入排序但使用不同增量的过程。
1 public static void shell_sort(int[] a) { 2 int N = a.length; 3 int d = N / 2;// 增量初始化为数组长度的一般,以后每次减半,直到增量为1。 4 while (d >= 1) { 5 for (int i = d; i < N; i++) { 6 for (int j = i; j >= d; j -= d) { 7 if (a[j] < a[j - d]) { 8 int t = a[j]; 9 a[j] = a[j - d]; 10 a[j - d] = t; 11 } 12 } 13 } 14 d = d / 2;//直到增量为1。 15 } 16 }
增量的选择对算法的性能影响很大,有很多论文研究了各种不同的递增系列,但都无法证明某个"序列" 是最好的。
在贴出书本上算法序列的选择的算法
1 public static <T> boolean less(Comparable v, Comparable w) { 2 return v.compareTo(w) < 0; 3 } 4 5 public static void exch(Object[] a, int i, int j) { 6 Object temp = a[i]; 7 a[i] = a[j]; 8 a[j] = temp; 9 } 10 11 public static <T> void sort(Comparable<T>[] a) { 12 int N = a.length; 13 int h = 1; 14 while (h < N / 3) 15 h = 3 * h + 1;// 1, 4, 13, 40 16 while (h >= 1) { 17 for (int i = h; i < N; i++) 18 //在子数组中进行插入排序将a[i]插入到a[j-h], a[i-2*h], a[i-3*h]....之中 19 for (int j = i; j >= h && less(a[j], a[j - h]); j -= h) { 20 exch(a, j, j - h); 21 } 22 h = h / 3; 23 } 24 }
使用10W个数字进行测试 如果选择第一种序列 使用 22754 微秒,第二种序列使用 161 微妙 差距都一个数量级啦,序列的选择对性能影响还是很大的。
posted on 2013-03-21 15:20 Arts&Crafts 阅读(267) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构