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 }
  • 相关阅读:
    Android中的5种数据存储方式
    Android Service
    Android BroadcastReceiver
    Android Intent
    Android Fragment
    Android 教学实验计划1
    【Android教学用例程序】计算器
    Android UI 基础知识
    Android 控件
    Android 计算器布局测试2
  • 原文地址:https://www.cnblogs.com/yanspecial/p/5535278.html
Copyright © 2011-2022 走看看