java面试算法之堆排序
来源:互联网 发布:王欣网络直播 编辑:程序博客网 时间:2024/06/09 22:23
/** * 堆排序 * 堆的概念:一个无序序列,{k1,k2,k3,k4,k5,k6,k7.......kn},当(ki<k(2i+1)&&ki<k(2i+2)) || (ki>k(2i+1) && ki>k(2i+2))) * 第一步:先初始化堆,怎样初始化堆呢?循环完全二叉树中的第(n/2-1)个节点(为啥从这个节点开始呢?因为二叉树排序应该从最下边开始往上边冒,而 * (n/2-1)是最后一个非叶子节点),那么循环多少次呢?循环n/2次。 * 第二步:把最后一个元素和第0个元素进行调换,然后重新初始化堆(这里初始化堆就只需要初始化第0个和第j个了,因为其他元素都输出了) * Created by wuxiaojun on 2017/12/15. */public class HeapSort { public static void main(String[] args) { int[] arrays = {99, 88, 101, 2, 9, 6, 22, 0, 123, 987, 6, 8, 19}; int length = arrays.length; // 初始化堆 for (int i = length / 2; i >= 0; i--) { sift(i, length, arrays); } // 将堆的最后一个元素和第0个元素进行调换并输出 for (int j = length - 1; j > 0; j--) { int temp = arrays[0]; arrays[0] = arrays[j]; arrays[j] = temp; sift(0, j, arrays); // 为什么是0和j呢?因为每次把第0个元素和最后一个元素进行互换了之后,需要重新初始化堆,但是这次初始化堆,只需要比较互换后的第0个比较它的孩子就好。 } forEach(arrays); } /*** * 初始化堆 * @param low * @param high */ public static void sift(int low, int high, int[] arrays) { int i = low; int j = 2 * i + 1; int temp = arrays[i]; while (j < high) { if (j < high - 1 && arrays[j + 1] > arrays[j]) { j++; // 拿到左右孩子最小的一个的索引 } if (temp < arrays[j]) { // 如果父亲的值小于孩子中最大的一个的值,则需要进行互换 arrays[i] = arrays[j]; // arrays[i] = arrays[j] = 95; i = j; // i = j = 5; j = 2 * i + 1; // j = 11; } else { j = high + 1; // 退出循环 } } arrays[i] = temp; // 这里为啥要把temp的值赋给arrays[i]呢?因为当temp < arrays[j]的时候,把j的索引赋给了i,所以i变成了j,这里理解其实就是j,但是执行44-46行代码之后把j的值重新计算了,所以就用i } public static void forEach(int[] arrgs) { for (int j = 0; j < arrgs.length; j++) { System.out.print(arrgs[j] + " "); } System.out.println("遍历完成"); }}
阅读全文