希尔排序与堆排序
2017-04-03 13:11
337 查看
1. 希尔排序
希尔排序也被称为“缩小增量排序”,其基本原理如下:先将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,然后对各个子序列分别进行直接插入排序,待整个待排序序列“基本有序后”,最后再对所有元素进行一次直接插入排序。
希尔排序的具体步骤如下:
1)选择一个步长序列 t1,t2,...,tk,满足 ti>tj(i<j),tk=1;
2)按步长序列个数 k,对待排序序列进行 k 趟排序;
3)每趟排序,根据对应步长 ti,将待排序序列分割成 ti 个子序列,分别对各个子序列进行直接插入排序。
程序示例如下;
public class SortShell { public static void shellSort(int[] array) { int length = array.length; int j, temp; for(int step = length/2; step > 0; step = step/2) { for(int i = step; i < length; i++) { temp = array[i]; for(j = i - step; j >= 0; j -= step) { if(temp < array[j]) { array[j + step] = array[j]; } else break; } array[j + step] = temp; } } } public static void main(String[] args) { int a[] = {5,4,9,8,7,6,0,1,3,2}; shellSort(a); for(int i = 0;i <a.length; i++) System.out.print(a[i] + " "); } }/* Output: 0 1 2 3 4 5 6 7 8 9 *///~
希尔排序的关键并不是随便地分组后各自排序,而是将相隔某个“增量”的记录组成一个子序列,实现跳跃式移动,使得排序的效率提高。
2. 堆排序
堆排序是一树形数据结构,在排序过程中,将 R[ 1 … n ] 看作一颗完全二叉树的顺序存储结构,利用完全二叉树中父结点和子结点之巅的内在关系来选择最小的元素。堆一般分为大顶堆和小顶堆两种不同的类型。对于给定的 n 个记录的序列(r(1),r(2),…,r(n)),当且仅当满足条件(r(i)>=r(2i)且 r(i)>=r(2i+1),i = 1, 2 ,…, n)时称之为大顶堆,此时,堆顶元素必为最大值。对于给定的 n 个记录的序列(r(1),r(2),…,r(n)),当且仅当满足条件(r(i)<=r(2i)且 r(i)<=r(2i+1),i = 1, 2 ,…, n)时称之为小顶堆,此时,堆顶元素必为最小值。
堆排序的思想是:
对于给定的 n 个记录,初始时把这些记录看作一棵顺序存储的二叉树,然后将其调整为一个大顶堆,然后将堆的最后一个元素与堆顶元素(即二叉树的根节点)进行交换后,堆的最后一个元素即为最大记录;接着将前(n-1)个元素(即不包括最大记录)重现调整为一个大顶堆,再将堆顶元素与当前元素的最后一个元素进行交换后得到次大的记录,重复该过程直到调整的堆中只剩下一个元素时为止,该元素即为最小记录,此时可得到一个有序序列。
堆排序主要包括两个过程:
(1)构建堆; (2)交换堆顶元素与最后一个元素的位置。
升序排序:构建大顶堆;交换堆顶元素与最后一个元素的位置。
降序排序:构建小顶堆;交换堆顶元素与最后一个元素的位置。
程序示例如下:
// 降序排序 public class SortHeap { public static void adjustMinHeap(int[] a, int pos, int len) { int temp, child; for(temp = a[pos]; 2*pos + 1 <= len; pos = child) { child = 2*pos + 1; if( child < len && a[child] > a[child+1] ) child++; if( a[child] < temp ) a[pos] = a[child]; else break; } a[pos] = temp; } public static void MinHeapSort(int[] array) { int i; int len = array.length; for(i = len/2 - 1; i >= 0; i--) adjustMinHeap(array,i,len-1); for(i = len - 1; i >= 0; i--) { int temp = array[0]; array[0] = array[i]; array[i] = temp; adjustMinHeap(array, 0, i-1); } } public static void main(String[] args) { int[] a = {5,4,9,8,7,6,0,1,3,2}; MinHeapSort(a); for(int i = 0; i < a.length; i++) System.out.print(a[i] + " "); } }/* Output: 9 8 7 6 5 4 3 2 1 0 *///~
堆排序方法对于记录较少的文件效果一般,但对于记录较多的文件还是很有效的,其运行时间主要耗费在创建堆和反复调整堆上。堆排序即使在最坏情况下,其时间复杂度也为O(nlogn)。
相关文章推荐
- 对c语言系统库函数、堆排序、希尔排序、折半插入排序、快速排序消耗时间的比较
- 插入排序,希尔排序,堆排序,归并排序,快速排序Java实现
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- Java实现常见排序--希尔排序、快排序、堆排序、归并排序等Java实现代码
- 基本的排序算法:冒泡排序、插入排序、希尔排序、选择排序、归并排序、快速排序、堆排序
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——JAVA实现
- C++排序:冒泡排序,简单选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 介绍堆排序、希尔排序和快速排序
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序,堆排序)
- 排序算法: 冒泡排序, 快速排序,希尔排序,直接插入排序 ,直接选择排序,归并排序,堆排序
- 几种常用的排序算法(快速排序,希尔排序,堆排序,选择排序,冒泡排序)
- 排序(冒泡排序,插入排序,希尔排序,选择排序,堆排序)
- 【排序】插入排序,希尔排序,选择排序,冒泡排序,堆排序详解及稳定性分析
- C语言排序算法集锦:选择排序,冒泡排序,插入排序,希尔排序,归并排序,堆排序,快排序
- 程序员必知的8大排序(①直接插入排序②希尔排序③简单选择排序④堆排序⑤冒泡排序⑥快速排序⑦归并排序⑧基数排序)
- 数据结构-排序算法详解(插入排序,希尔排序,堆排序,归并排序,快速排序,桶式排序)
- Java基础篇之----排序(快速排序、冒泡排序、堆排序、简单选择排序、 希尔排序、直接插入排序)
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 面试珠玑 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结