zoukankan      html  css  js  c++  java
  • 堆排序

      1 package com.yan.algorithm;
      2 
      3 import java.util.Arrays;
      4 
      5 public class HeapSortTest {
      6     /*
      7      * 堆得规则:任何一个parent节点都比其左右子节点大(或者小)。
      8      * 堆排序步骤:
      9      * 1.初始化堆,即从倒数第一个parent节点开始往前,进行调整,使任何一个parent节点都比其左右子节点大(或者小)。
     10      * 2.堆初始化后的堆进行排序,每次将堆顶节点和堆最后一个节点进行交换,并调整,循环n次。
     11      * 三个方法:
     12      * (1)初始化 heapInit()
     13      *         从倒数第一个parent节点开始往前,进行调整
     14      * (2)调整 heapify()
     15      *         由parent节点找到其2个子节点,并交换使得parent节点为最大,递归调整交换的子树
     16      * (3)排序 sort()
     17      *         每次将堆顶节点和堆最后一个节点进行交换,并调整,循环n次
     18      */
     19 
     20     private static int[] data = new int[] { 12, 13, 14, 46, 15, 65, 99 };
     21 
     22     public HeapSortTest() {
     23     }
     24 
     25     public static void main(String[] args) {
     26 
     27         heapInit(data, data.length);
     28         sort(data);
     29         System.out.println(Arrays.toString(data));
     30     }
     31 
     32     /**
     33      * 创建初始堆,若堆排序目的是为了递增排序,则初始堆是一个最大堆。
     34      * 
     35      * @param data
     36      * @param length为数组长度
     37      */
     38     public static void heapInit(int[] data, int length) {
     39         // 从最后一个parent节点开始调整。
     40         int start = getParentIndex(length - 1);
     41         // 因为从倒数第一个parent节点开始往前的每一个节点都要调整,所以要用for循环。
     42         for (int i = start; i >= 0; i--) {
     43             heapify(data, length, i);
     44         }
     45     }
     46 
     47     /*
     48      * 在parent和左右子节点3者之间交换调整,使得parent是3者中最大值.
     49      * heapsize是需要调整的节点数的长度,用来判断子节点是否越界(和在sort方法中设置调整的范围,因为已排序的后面一部分不需要再调整了)。
     50      */
     51     public static void heapify(int[] data, int heapsize, int start) {
     52         int largest = start;
     53         int leftChild = getLeftChildIndex(start);
     54         int rightChild = getRightChildIndex(start);
     55         if (leftChild < heapsize && data[largest] < data[leftChild]) {
     56             largest = leftChild;
     57         }
     58         if (rightChild < heapsize && data[largest] < data[rightChild]) {
     59             largest = rightChild;
     60         }
     61         /*
     62          * 如果发生了交换,则该子节点的子树也不再符合堆的规则。 因此,需要继续对其子节点进行递归调整。
     63          */
     64         if (largest != start) {
     65             swap(data, start, largest);
     66             heapify(data, heapsize, largest);
     67         }
     68 
     69     }
     70 
     71     /**
     72      * 对初始化过的堆进行排序(将最大堆排序为递增堆 “即,每次将堆顶元素和堆末尾的元素进行交换,然后从堆顶元素开始进行调整”,
     73      * 或者将最小堆排序为递减堆。“即,同上”)
     74      * 
     75      * @param data
     76      */
     77     public static void sort(int[] data) {
     78         for (int i = data.length - 1; i > 0; i--) {
     79             swap(data, i, 0);
     80             heapify(data, i, 0);
     81         }
     82     }
     83 
     84     public static void swap(int[] data, int x, int y) {
     85         int temp = data[x];
     86         data[x] = data[y];
     87         data[y] = temp;
     88     }
     89 
     90     public static int getLeftChildIndex(int parent) {
     91         return (parent << 1) + 1;
     92     }
     93 
     94     public static int getRightChildIndex(int parent) {
     95         return (parent << 1) + 2;
     96     }
     97 
     98     public static int getParentIndex(int child) {
     99         return (child - 1) >> 1;
    100     }
    101 
    102 }
  • 相关阅读:
    vue 中input的输入限制
    PC端百度地理围栏、绘制工具以及判断当前坐标是否再围栏中
    js判断鼠标点击的是哪个键
    vue过滤器的使用
    3.Mybatis的配置解析
    2.MyBatis的CRUD操作
    4.JVM类加载器深入解析及重要特性剖析
    3.JVM的接口初始化规则与类加载器准备阶段和初始化阶段的重要意义分析
    2.JVM的类加载器
    1.JVM如何学习
  • 原文地址:https://www.cnblogs.com/yanspecial/p/5535278.html
Copyright © 2011-2022 走看看