堆排序(七)

来源:互联网 发布:数控铣床编程简单图案 编辑:程序博客网 时间:2024/06/06 08:54
import java.util.Arrays;/** *  * @author lixuwu *堆排序两步:建立堆的过程,堆的调整过程 *堆中的元素用数组来进行存储,标号从1开始;结点i的左右子树为2i和2i+1,堆的最后一个非叶结点的编号为n/2 *堆的大小即为堆中元素的个数,不等于数组的大小(这里在堆得调整过程中很重要) *对于堆的存储结构数组,第一个元素的下标为0,一般用一个特殊的数字区分,不参与堆的排序过程 */public class HeapSort {/** *  * @param array * @param i需要调整的堆元素在数组中的位置。一般从堆顶(1)或者堆的堆的最后一个非叶节点(n/2)开始 * @param n堆的大小,也就是堆中存储元素的个数 *  * 以下向下调整的过程是建立一个大顶堆的过程,从堆中某一个位置i开始,分别与他的左右子树(2i,2i+1)进行比较, * 找出i,2i,2i+1中最大的元素t,如果最大元素t=i,结束调整。如果最大元素t !=i,则两者数值交换,i=t,继续向下调整 */public static void siftdown(int array[],int i,int n){int t,temp,flag=0;//flag用来标记是否需要继续向下调整//当i结点有儿子(其实是至少有左儿子)并且需要继续调整的时候循环就执行while(i*2<=n && flag==0){//首先判断它和左儿子的关系,并用t记录较大结点编号if(array[i] < array[2*i]){t = 2*i;}else{t = i;}//如果结点i有右儿子,再对右儿子进行讨论,如果右儿子的值更大,更新较大的结点tif(i*2+1 <=n){if(array[t] <array[i*2+1])t = i*2+1;}//如果发现最大的结点编号不是自己,说明子结点中有比父结点更大的。此时将父结点与子结点进行交换if(t != i){temp = array[i];array[i] = array[t];array[t] = temp;i = t;//更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整}else{flag = 1;//否则说明当前的父结点已经比两个子结点都要大了,不再进行调整了}}//end while;}//建立堆的函数public static void creat(int array[]){int i;int n = array.length-1;//因为堆的第一个结点编号从1开始,所有要排除数组中下标为0的那个元素//从最后一个非叶结点n/2到第1个依次进行向下调整的过程for(i=n/2;i>=1;i--)siftdown(array, i,n);}//堆排序:从大顶堆开始,每次将堆顶元素与堆尾元素交换,堆的大小减一,然后再调整堆顶元素。如此反复//直到堆的大小变为1为止。此时数组中的元素就已经是排序好的了public static void heapSort(int array[]){int n = array.length-1;//表示堆中元素的个数while(n>1){int temp = array[1];array[1] = array[n];array[n] = temp;n--;siftdown(array, 1,n);}}public static void main(String[] args) {// TODO Auto-generated method stubint a[] ={0,2,4,1,5,3,9,7,8,6};creat(a);heapSort(a);System.out.println(Arrays.toString(a));}}

运行结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

0 0