数据结构算法之排序系列Java、C源码实现(4)--堆排序

来源:互联网 发布:淘宝网客户端官方下载 编辑:程序博客网 时间:2024/06/05 20:32

 堆是一种树形结构,堆排序是对直接选择排序的有效改进。实现堆排序需要解决三个问题:

1.构建完全二叉树:先把待排序序列构建成一棵完全二叉树。   

2.把无序序列建成的完全二叉树调成一个有序堆。

然后根据以下定义建堆:

   n个元素的序列{k1, k2, …., kn}当且满足下述关系时,称之为堆。

 

前者称为小顶堆(小根堆),后者称为大顶堆(大根堆)。

从一个无序序列建堆的过程就是一个反复“筛选”的过程。“筛选”只需从第个元素开始(完全二叉树中最后一个非终端结点)。

堆排序的最坏时间复杂度为O(nlog2n),它的平均性能较接近于最坏情况。在记录数较少的情况下,不适宜用堆排序。堆排序是就地排序,辅助空间为O(1),它是不稳定的排序。

Java代码:

public class HeapSort {public static void main(String[] args) {int array[] = {5, 18, 151, 138, 160, 63, 174, 169, 79, 200};showArray(array);System.out.println("\n排序后");heapSort(array);showArray(array);}/** a 待排数组 rootIndex 本次堆化的根 maxHeapIndex 本次堆化所达到的堆数组最大索引*/private static void maxHeapify(int a[],int rootIndex,int maxHeapIndex){int lChild = rootIndex*2+1;int rChild = rootIndex*2+2;int largeIndex = rootIndex;if(lChild<=maxHeapIndex && a[lChild]>a[rootIndex])largeIndex = lChild;if(rChild<=maxHeapIndex && a[rChild]>a[largeIndex])largeIndex = rChild;if(largeIndex != rootIndex){swap(a,largeIndex,rootIndex);maxHeapify(a,largeIndex,maxHeapIndex);} }private static void swap(int[] arr,int a,int b){int temp = arr[a];arr[a] = arr[b];arr[b] = temp;}private static void heapSort(int[] a) {int i = 0;int maxHeapIndex = a.length -1;//首先建立一个堆,大根堆是要满足父亲节点都是大于子节点的 for(i=(maxHeapIndex-1)/2;i>=0;i--){maxHeapify(a,i,maxHeapIndex);}for(i=maxHeapIndex;i>=1;i--){swap(a,0,i);//交换之后,继续堆化时,堆数组的索引要减去1,把最大的数字就直接保存到末尾了 maxHeapify(a,0,i-1);}}private static void showArray(int[] a) {for (int i = 0; i < a.length; i++) {System.out.print(a[i] + " ");}}}


c代码:

//堆排序

#include<stdio.h> #include<malloc.h>void showArray(int a[],int len){for(int i=0;i<len;i++){printf("%d  ",a[i]);}}void swap(int *a,int *b){int temp = *a;*a = *b;*b = temp;}/*a   待排数组rootIndex 本次堆化的根maxHeapIndex 本次堆化所达到的堆数组最大索引 */void maxHeapify(int a[],int rootIndex,int maxHeapIndex){int lChild = rootIndex*2+1;int rChild = rootIndex*2+2;int largeIndex = rootIndex;if(lChild<=maxHeapIndex && a[lChild]>a[rootIndex])largeIndex = lChild;if(rChild<=maxHeapIndex && a[rChild]>a[largeIndex])largeIndex = rChild;if(largeIndex != rootIndex){swap(&a[largeIndex],&a[rootIndex]);maxHeapify(a,largeIndex,maxHeapIndex);} }/*a: 待排序数组长度len : 数组长度 */void heapSort(int a[],int len){int i = 0;int maxHeapIndex = len -1;//首先建立一个堆,大根堆是要满足父亲节点都是大于子节点的 for(i=(maxHeapIndex-1)/2;i>=0;i--){maxHeapify(a,i,maxHeapIndex);}for(i=maxHeapIndex;i>=1;i--){swap(&a[0],&a[i]);//交换之后,继续堆化时,堆数组的索引要减去1,把最大的数字就直接保存到末尾了 maxHeapify(a,0,i-1);}}int main(){int a[] = {5, 18, 151, 138, 160, 63, 174, 169, 79, 200};int len = sizeof(a)/sizeof(int);showArray(a,len);heapSort(a,len);printf("\n排序后:\n");showArray(a,len);return 0; } 

堆排序就是先建立堆,然后对从最后一个非叶子节点开始,进行不断交换的过程

1 0
原创粉丝点击