简单排序算法实现——堆排序
2013-02-04 22:03
477 查看
堆排序 (Heap Sort) 是利用了数据结构:完全二叉树来进行排序的算法。其基本原理先要将完全二叉树以数组的形式实现出来。再者,用于堆排序的完全二叉树必须满足最大堆(Max Heap) 的性质,即任意一个非叶子节点上的值都应该比其左孩子和右孩子的值小,满足该性质的即称为最大堆。
先阐述在数组上实现完全二叉树的原理:
对于数组下标从0开始的java语言,对于给定的节点下标 i ,其父节点下标为 (i-1)/2, 左孩子节点下标为 2*i+1, 右孩子的节点下标为 2*(i+1).
另外,一个重要的结论是,最后一个非叶子节点的下标是a.length/2-1, 从a.length/2开始后面的下标对应的都是叶子节点,没有孩子。
堆排序的实现需要三个操作。
第一个是最大堆调整操作 (MAX_HEAPIFY) , 接收参数 a[i], i 将以 i 为根节点的子树做调整,使得子节点永远小于父节点,从而满足最大堆性质。
第二个操作是创建最大堆操作 (BUILD_MAX_HEAP),将待排序数组中的元素排列成最大堆的数组实现。调用时,从最后一个非叶子节点的下标a.length/2-1开始向前遍历使用最大堆调整操作。
第三个操作是堆排序操作 (HeapSortOnMaxHeap),每次移除整个堆的根节点 (即当前的最大元素),然后进行堆调整的递归运算。
为了实现原地排序,加入指标heapSize,与a.length区别开来,在堆排序操作中,移除最大元素的操作实现为将第一个元素交换到数组的最后,然后heapSize减一,表明该元素已经不在堆中了。
下面给出全部的java代码实现,其中加了一个公共类的HeapSort作为驱动,依次调用创建最大堆操作和堆排序操作,同时加入了计算父亲/孩子节点对应下标的辅助方法。
堆排序的平均时间复杂度为O(nlogn), 该复杂度同时也为最优时间复杂度。
附图一张:
至今基本排序算法的实现练习暂时告一段落,这些排序算法的一些高级优化或特性,以及其他高级排序算法,留待以后再做研究。
接下来开始一些基本数据结构的实现练习。
先阐述在数组上实现完全二叉树的原理:
对于数组下标从0开始的java语言,对于给定的节点下标 i ,其父节点下标为 (i-1)/2, 左孩子节点下标为 2*i+1, 右孩子的节点下标为 2*(i+1).
另外,一个重要的结论是,最后一个非叶子节点的下标是a.length/2-1, 从a.length/2开始后面的下标对应的都是叶子节点,没有孩子。
堆排序的实现需要三个操作。
第一个是最大堆调整操作 (MAX_HEAPIFY) , 接收参数 a[i], i 将以 i 为根节点的子树做调整,使得子节点永远小于父节点,从而满足最大堆性质。
第二个操作是创建最大堆操作 (BUILD_MAX_HEAP),将待排序数组中的元素排列成最大堆的数组实现。调用时,从最后一个非叶子节点的下标a.length/2-1开始向前遍历使用最大堆调整操作。
第三个操作是堆排序操作 (HeapSortOnMaxHeap),每次移除整个堆的根节点 (即当前的最大元素),然后进行堆调整的递归运算。
为了实现原地排序,加入指标heapSize,与a.length区别开来,在堆排序操作中,移除最大元素的操作实现为将第一个元素交换到数组的最后,然后heapSize减一,表明该元素已经不在堆中了。
下面给出全部的java代码实现,其中加了一个公共类的HeapSort作为驱动,依次调用创建最大堆操作和堆排序操作,同时加入了计算父亲/孩子节点对应下标的辅助方法。
public class HeapSort{ private static int heapSize; private static int indexOfLeft(int root){ return (2*root+1); } private static int indexOfRight(int root){ return 2*(root+1); } private static int indexOfParent(int root){ return (root-1)/2; } //This method will examine node at position i and its two childs. //If i is smaller than one of its child, it will adjust it to maintain it as //a max heap private static <AnyType extends Comparable<? super AnyType>> void MAX_HEAPIFY(AnyType[] a, int i){ int l=indexOfLeft(i); int r=indexOfRight(i); int indexOfMax; //Condition l,r<=heapSize ensures that operation on leaf nodes will be tolerated. if(l<=heapSize-1&&a[l].compareTo(a[i])>0) indexOfMax=l; else indexOfMax=i; //If max==a[i], no operation at last; if(r<=heapSize-1&&a[r].compareTo(a[indexOfMax])>0) indexOfMax=r; if(indexOfMax!=i){ AnyType temp=a[i]; a[i]=a[indexOfMax]; a[indexOfMax]=temp; MAX_HEAPIFY(a, indexOfMax); } } private static <AnyType extends Comparable<? super AnyType>> void BUILD_MAX_HEAP(AnyType[] a){ heapSize=a.length; for(int i=a.length/2-1;i>=0;i--){ MAX_HEAPIFY(a,i); } } private static <AnyType extends Comparable<? super AnyType>> void HeapSortOnMaxHeap(AnyType[] a){ AnyType temp; for(int i=a.length-1;i>=1;i--){ temp=a[0]; a[0]=a[i]; a[i]=temp; heapSize--; MAX_HEAPIFY(a,0); } } public static <AnyType extends Comparable<? super AnyType>> void HeapSort(AnyType[] a){ BUILD_MAX_HEAP(a); HeapSortOnMaxHeap(a); } public static void main(String[] args){ System.out.println("Heap Sort:"); Integer[] elements={3,4,1,8,10,2,0,6,5}; System.out.print("Original elements: "); for(int i=0;i<elements.length;i++) System.out.print(elements[i]+" "); System.out.println(); HeapSort(elements); System.out.print("After sorting: "); for(int i=0;i<elements.length;i++) System.out.print(elements[i]+" "); System.out.println(); } }
堆排序的平均时间复杂度为O(nlogn), 该复杂度同时也为最优时间复杂度。
附图一张:
至今基本排序算法的实现练习暂时告一段落,这些排序算法的一些高级优化或特性,以及其他高级排序算法,留待以后再做研究。
接下来开始一些基本数据结构的实现练习。
相关文章推荐
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- 最简单的排序算法之一冒泡排序----js实现
- 冒泡排序、选择排序、堆排序、快速排序、插入排序算法复杂度分析与算法实现(自己总结与转)
- C语言实现 排序源程序(包括直接插入、希尔、冒泡、快速、简单选择、堆排序)
- 查找""排序""简单数学计算" "简单算法"[Java实现](数据结构和算法)(复习)(持续更新
- 算法导论之插入排序,选择排序,归并排序,冒泡排序,希尔排序,堆排序,快速排序的c语言实现
- 简单排序Java实现(三):希尔排序,堆排序
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- 【数据结构与算法】【排序】堆排序的代码实现
- C语言实现 排序源程序(包括直接插入、希尔、冒泡、快速、简单选择、堆排序)
- 简单排序算法之堆排序
- 每天一个数据结构——三种简单排序算法及Java实现
- 转载:yangsen600的C语言实现的简单排序算法汇总
- C#中定义数组和一个简单排序算法实现。
- PHP实现排序堆排序(Heap Sort)算法
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- 插入排序,合并排序,堆排序,快速排序,计数排序的实现(算法导论)
- 【算法】排序 (一):插入排序&希尔排序&选择排序&堆排序(C++实现)
- 三种简单排序算法及实现(引用)
- 【数据结构与算法】【排序】简单选择排序的代码实现