堆排序-2

package com.ghj.util;

public class sortAlgorithm<T extends Comparable<T>> {

    // 交换索引i和索引j的值
    private void swap(T[] data, int i, int j) {
        T tmp;
        tmp = data[i];
        data[i] = data[j];
        data[j] = tmp;
    }

    // -----堆排序 时间复杂度O(nlogn)-----
    public void heapSort(T[] data) {
        int arrayLength = data.length;

        // 循环建大顶堆
        for (int i = 0; i < arrayLength - 1; i++) {
            // 建堆
            builMindHeap(data, arrayLength - 1 - i);
            // 交换堆顶和最后一个元素
            swap(data, 0, arrayLength - 1 - i);
        }
    }

    // 对data数组从0到lastIndex建大顶堆
    private void builMaxdHeap(T[] data, int lastIndex) {
        // 从lastIndex处节点(最后一个节点)的父节点开始
        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
            // k 保存当前正在判断的节点
            int k = i;
            // 如果当前节点有子节点
            while (k * 2 + 1 <= lastIndex) {
                // 当前节点的左子节点的索引
                int biggerIndex = 2 * k + 1;
                // 如果biggerIndex 小于lastIndex ,则biggerIndex + 1;
                // 代表的k节点的右子节点存在
                if (biggerIndex < lastIndex) {
                    // 如果右子节点的值比较大
                    if (data[biggerIndex].compareTo(data[biggerIndex + 1]) < 0) {
                        // biggerIndex总是记录较大的子节点的索引
                        biggerIndex++;
                    }
                }

                // 如果k节点的值小于其较大的子节点的值
                if (data[k].compareTo(data[biggerIndex]) < 0) {
                    // 交换他们
                    swap(data, k, biggerIndex);
                    // 将biggerIndex赋给k,开始下一次循环
                    // 重新保证k节点的值大于其左右子节点的值
                    k = biggerIndex;
                } else {
                    break;
                }
            }
        }
    }

    // 对data数组从0到lastIndex建小顶堆
    private void builMindHeap(T[] data, int lastIndex) {
        // 从lastIndex处节点(最后一个节点)的父节点开始
        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
            // k 保存当前正在判断的节点
            int k = i;
            // 如果当前节点有子节点
            while (k * 2 + 1 <= lastIndex) {
                // 当前节点的左子节点的索引
                int minnerIndex = 2 * k + 1;

                // 如果minnerIndex 大于 lastIndex ,则minnerIndex + 1;
                // 代表的k节点的右子节点存在
                if (minnerIndex < lastIndex) {
                    // 如果右子节点的值比较小
                    if (data[minnerIndex].compareTo(data[minnerIndex + 1]) > 0) {
                        // minnerIndex总是记录较小的子节点的索引
                        minnerIndex++;
                    }
                }

                // 如果k节点的值大于其较小的子节点的值
                if (data[k].compareTo(data[minnerIndex]) > 0) {
                    // 交换他们
                    swap(data, k, minnerIndex);
                    // 将minnerIndex赋给k,开始下一次循环
                    // 重新保证k节点的值小于其左右子节点的值
                    k = minnerIndex;
                } else {
                    break;
                }
            }
        }
    }

    private static String getString(Comparable[] data) {
        String result = "";
        for (int i = 0; i < data.length; i++) {
            result = result + data[i].toString();
        }
        return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        sortAlgorithm sort = new sortAlgorithm<>();
        Comparable[] data = { 1, 5, 2, 9, 3 };
        System.out.println("Before sort : " + getString(data));
        sort.heapSort(data);
        System.out.println("After sort : " + getString(data));
    }

}
原文地址:https://www.cnblogs.com/yunkong/p/4479499.html