堆排序算法(简单易懂)(大顶堆)

package com.czf.sortTest.sort;

/**
 * 大顶堆 排序
 *
 * @author czf
 * @date 20180726
 */
public class HeapSort {

    public static void heapSort(int[] data) {
        HeapNode[] heap = initHeap(data);
        sort(heap, heap.length - 1, data);
    }

    /**
     * 建立堆的的节点关系
     * 从N/2节点到根节点开始初始化堆
     *
     * @param data
     * @return
     */
    private static HeapNode[] initHeap(int[] data) {
        HeapNode[] heap = new HeapNode[data.length];
        for (int i = 0; i < data.length; i++) {
            heap[i] = new HeapNode(data[i]);
        }
        for (int i = 0; i < data.length; i++) {
            int left = 2 * i + 1, right = 2 * i + 2;
            heap[i].left = left < data.length ? heap[left] : null;
            heap[i].right = right < data.length ? heap[right] : null;
        }
        for (int i = heap.length / 2; i >= 0; i--) {
            adjustDown(heap[i]);
        }
        return heap;
    }

    /**
     * 排序
     *
     * @param heap
     * @param end  调换end位置的元素和堆顶元素,从上至下调整
     */
    private static void sort(HeapNode[] heap, int end, int[] data) {
        data[end] = heap[0].value;
        if (end <= 0)
            return;
        swap(heap[0], heap[end]);//堆顶最大元素放置结尾处
        deleteLastNode(heap, end);
        adjustDown(heap[0]);//从上到下调整堆
        sort(heap, --end, data);
    }

    /**
     * 将当前节点下沉到合适的位置
     *
     * @param node
     */
    private static void adjustDown(HeapNode node) {
        while (node.left != null || node.right != null) {
            if (node.left == null) {
                if (node.right.value > node.value) {
                    swap(node.right, node);
                    node = node.right;
                    continue;
                }
            }
            if (node.right == null) {
                if (node.left.value > node.value) {
                    swap(node.left, node);
                    node = node.left;
                    continue;
                }
            }
            if (node.left != null && node.right != null) {//左右都不为空
                if (node.left.value >= node.right.value && node.left.value > node.value) {
                    swap(node.left, node);
                    node = node.left;
                    continue;
                }
                if (node.right.value > node.left.value && node.right.value > node.value) {
                    swap(node.right, node);
                    node = node.right;
                    continue;
                }
            }
        }
    }

    private static void deleteLastNode(HeapNode[] heap, int end) {
        int fatherIndex1 = end / 2;
        if (heap[fatherIndex1].left == heap[end])
            heap[fatherIndex1].left = null;//删除尾部最大元素
        int fatherIndex2 = end / 2 - 1;
        if (fatherIndex2 >= 0 && heap[fatherIndex2].right == heap[end])
            heap[fatherIndex2].right = null;//删除尾部最大元素
    }

    private static void swap(HeapNode i, HeapNode j) {
        int temp = i.value;
        i.value = j.value;
        j.value = temp;
    }
}

class HeapNode {
    HeapNode left;
    HeapNode right;
    int value;

    public HeapNode(int value) {
        this.value = value;
    }
}

 

package com.czf.sortTest;

import com.czf.sortTest.sort.HeapSort;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        // write your code here
        int[] data = {45, 44, 23, 22, 1, 43, 99, 56, 0, 100, 45, 45, 45, 5, 45, 6, 45, 25623453, 258};
         //int[] data = {45, 44, 23, 22, 1, 43, 99, 56};

        //方法一:快速排序:
        // QuickSort.quickSort(data, 0, data.length - 1);

        //方法二:堆排序
        HeapSort.heapSort(data);
        System.out.println("sorted: " + Arrays.toString(data));
    }


}
点赞