堆的相关知识就不说了,堆排序的核心就是堆调整函数怎么写,要注意的是堆调整过程就是在对要排序的数组上做相应的交换,那种画二叉树的

方式知识帮助我们怎么理解这个过程,并不需要其他的什么数据结构。

构造大根堆的过程

 1     public static void HeapAdjust(int[] array,int parent,int length) {
 2         int tmp=array[parent];  //tmp保存当前父节点的值
 3         int child=2*parent+1;  //child指向父节点的左孩子节点
 4         
 5         while(child<length) {     //当父节点有子节点时进行循环
 6             //如果存在右孩子节点而且右孩子节点大于左孩子节点,就将child指向右孩子节点
 7             if(child+1<length && array[child+1]>array[child])
 8                 child++;
 9             //如果父节点大于等于child节点,就结束循环
10             if(tmp>=array[child]) {
11                    System.out.println(Arrays.toString(array));
12                 break;}
13             array[parent]=array[child]; //将父节点的值变为child节点的值
14             parent=child;               //满足条件就继续向下调整
15             child=2*parent+1;
16             array[parent]=tmp;        //将当前父节点的值变为tmp
17             System.out.println(Arrays.toString(array));
18         }
19     }
20     public static void HeapSort(int[] array) {
21         // 循环建立初始堆,从length/2处开始
22         int length=array.length;
23         for(int i=array.length/2;i>=0;i--) {
24             HeapAdjust(array,i,length);
25         }
26 }

 

 

注意这儿HeapSort只是建立初始堆,还没排序,我们在HeapAdjust里打印出了每一步对应的array的变化,例如要排序的数组是{1,3,4,5,2,6,9,7,8,0},则构造过程如下:

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

 

这儿碰到了个小坑,注意输出一个array时输出的时内存地址,要输出一个数组,要用Arrays.toString(array)

排序过程

 1     public static void HeapSort(int[] array) {
 2         // 循环建立初始堆,从length/2处开始
 3         int length=array.length;
 4         for(int i=array.length/2;i>=0;i--) {
 5             HeapAdjust(array,i,length);
 6         }
 7         for(int i=array.length-1;i>0;i--) {
 8             int tmp=array[i];
 9             array[i]=array[0];
10             array[0]=tmp;
11             HeapAdjust(array,0,i);
12             System.out.println(Arrays.toString(array));   //输出每一步交换并调整后的数组
13         }
14     }

 

我们每一步都输出中间结果,如下:

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

 

碰到的一个问题

就是HeapAdjust函数为什么要写一个参数length?就不能在函数内部自定义一个变量来保存数组的长度吗???

原因是在排序时,每交换一个元素,我们只需对剩下的还没排序好的元素进行堆调整,这儿还没排好的元素个数就是i 。

看的眼睛疼,吃饭去,哈哈!!!

posted on 2019-01-19 20:59  羊刀塔姆  阅读(105)  评论(0)    收藏  举报