堆排序分析

来源:互联网 发布:数据库概要设计 编辑:程序博客网 时间:2024/05/18 14:44

关于堆排序,时间空间复杂度大家都知道就不说了,堆排序涉及到两种遍历的方式,以小顶堆为例简单的讲一下:

(1)向上遍历,

如果我们采取不断的向一个空数组中插入数值的方式来初始化堆,为了保持小顶堆的性质,新插入的数值就要不断向堆的上方搜索,插入到新的位置

(2)向下遍历

向下遍历的发生有两种情况,

一是已知一个未排序的数组,为了将该数组变成小顶堆,那么从最后一个拥有子节点的节点开始,向该节点的下方遍历,将该节点插入到新的位置。

二是在小顶堆取出一个数之后,将数组末尾的数放入到根节点中后,根节点需要重新向下遍历。


有人会问,为啥一会向上遍历,一会向下遍历呢,因为向上遍历的前提是该节点的上方已经满足小顶堆的性质,而向下遍历是因为该节点的下方(即所有子节点)已经满足小顶堆的性质。

代码如下:

package Sort;//小顶堆public class HeapSort {//通过插入数据形成小顶堆public void insertHeap(int a[],int i){int temp=a[i];int j=(i-1)/2;while(j>=0&&i!=0){if(a[j]<=temp)break;a[i]=a[j];i=j;j=(j-1)/2;}a[i]=temp;}//从节点i向下遍历重新调整public void fixAfterGetMin(int a[],int i,int n){int temp=a[i];int j=i*2+1;while(j<n){if(j+1<n&&a[j+1]<a[j])j=j+1;if(a[j]>=temp)break;a[i]=a[j];i=j;j=j*2+1;}a[i]=temp;}//原始数组直接小顶堆化public void convertToMinHeap(int a[],int n){for(int i=n/2-1;i>=0;i--){fixAfterGetMin(a,i,n);}}//输出不递减序列public void display(int a[],int n){for(int i=1;i<=n;i++){System.out.print(a[0]+" ");a[0]=a[n-i];fixAfterGetMin(a,0,n-i);}}public void initial(int a[]){a[0]=10;insertHeap(a,0);a[1]=4;insertHeap(a,1);a[2]=9;insertHeap(a,2);a[3]=7;insertHeap(a,3);a[4]=8;insertHeap(a,4);a[5]=5;insertHeap(a,5);a[6]=11;insertHeap(a,6);a[7]=23;insertHeap(a,7);a[8]=-1;insertHeap(a,8);System.out.println("退出初始函数");}public static void main(String[] args){HeapSort hs=new HeapSort();int a[]=new int[10];hs.initial(a);hs.display(a, 9);int[] b={10,4,9,7,8,5,11,23,-1};hs.convertToMinHeap(b, b.length);hs.display(b, b.length);}}

0 0
原创粉丝点击