Heap sort algorithm of those things

Algorithms and data structures may be the most junior programmers do not like to know before, after all, involves a lot of mathematical algorithms, before had seen some of the teacher to explain the program, explained the programmer should be aware of mathematical knowledge, if carefully understand the words, should find that, no matter what programming language contains a mathematical concepts, but also, more in-depth study of the need for more knowledge of algorithms and data structures

Foreword

Heap sort algorithm in a sort, in itself is not particularly complicated and required careful understanding can understand, write this mainly because of the source involved in the study, but is itself also needs to be done in a time of learning algorithms and data structures summary, it is described here knowledge heap Sort

definition

Reference Wikipedia explanation:

HEAPSORT (English: Heapsort) refers to a sorting algorithm such a data structure designed for use heap. A stack is nearly complete binary tree structure, while meeting the bulk properties: i.e. the key or index child node is always less than (or greater than) its parent node.

In terms ascending order described, to convert the maximum stack array (Max-Heap Heap), which is a bulk properties meet the maximum (Max-Heap Property) binary tree: For each node except the root i, A [parent (i)] ≥ A [i]. Repeat the maximum value taken from the maximum stack node (the root node and the last exchange, the last switching node after the removal of the stack), and so maintaining the maximum accumulation of the residual bulk properties.

Heapsort must understand 'heap' feature of this data structure, not rote, heap understand this data structure is the most important

Explanation

In terms of ascending order, we need to use the maximum heap to find the maximum of the value, because the maximum heap property indicates that the parent requires greater than or equal child nodes, then the binary tree root must be the greatest value of this heap, then the maximum value with the last switching node, such a node is the last maximum value. A maximum value represented by the node after the last does not participate in the max heap sorting process, the remaining nodes can be obtained by repeating this process a number of columns in ascending

Descending you need to use the minimum heap to find out that the minimum value of the other processes as above

Typically, the stack is achieved by a one-dimensional array, arranged in ascending order as an example the entire implementation process is as follows:

  1. The array sorted according to the number of all binary form condemnation
  2. From the last non-leaf node, then the comparison value is present and its size of the child with the child node, if it is less than the maximum child node, the switching node, which node will be updated to the maximum value subtree
  3. If the parent and child nodes are swapped, it may destroy the pile characteristics of the child nodes, in order to satisfy the characteristics of the stack, it is necessary to satisfy the processing conditions child node, recursively until all child nodes 2 satisfy the condition
  4. Repeat steps 2 and 3 until the root node traversal cycle forward
  5. The root node, i.e., top of the stack (now the first value in the array) and exchange the last value
  6. Array length minus 1 (excluding a maximum value has been calculated last), repeated 1-5 until sorted array length is 1, it indicates that the sort is complete

The first step is to represent a binary tree in an array, without any code that operation, part of the array to be sorted imagine binary tree

Whole is divided into two parts, wherein a portion of the maximum stack array, wherein another portion of the array nodes exchange

for example

For example described herein, the process of implementation, such as arrays [32, 4, 14, 56, 33, 78], the sorting process is as follows

The first step, the binary tree arrangement of the array

Heap sort -1

The second step, to find the last non-14, and compare the size of the child with the leaf node 14 is less than 78, 78 and 14 will be switched, switching node 14 continue to look at the position, no child node, without validating down

Heapsort -2

The third step, a comparison before continuing node 4, the maximum, 4, 56 exchange position of the sub node 56 and continue to look after the switch node 4, no child node, without validating down

Heap sort -3

The fourth step, a comparison before continuing node, the child node 78 of the maximum 32, the exchange 32 and 78 continue to look after the exchange location 32, to verify, 32 is greater than 14, without a swap

Heap sort -4

After performing the previous step, we can see that the whole stack is balanced, the array is not ordered, so to understand, we find that the maximum heap pile top, top of the heap is the heap maximum value, that is the root node, the element array index 0, the next thing is to keep the process cycle

The top of the stack and an array element 78 the last value switching position in which the top of the stack element 14 becomes, the capacity of stack is decremented by 1, we need to rebalance the entire stack (the last stack 78 is no longer involved balance)

A fifth step, balance resumes from the last non-leaf node, the node 56 has balance, the exchange 14 and 56, continue to look at the exchange position 14, 33 is greater than 14, 33 and 14 exchange, continue to look at the position of the switching node 14, no child nodes, do not proceed with the verification down

Heap sort -5

Heap sort -6

Previous executed, and balance the entire stack, the top of the stack element exchange capacity of the reactor was continued for 1 minus balance

A sixth step, continuing from the last non-leaf nodes start equilibrium, a balance has 33 nodes, 14 and 33 exchange, the exchange position continue to look at the 14, 14 has been balanced, it is operated without a swap

Heap sort -7

Previous executed, and balance the entire stack, the top of the stack element exchange capacity of the reactor was continued for 1 minus balance

A seventh step, balance resumes from the last non-leaf nodes, exchanging 4 and 32, continue to look at the exchange position 4, no child nodes, operating without exchanging the

Heap sort -8

Previous executed, and balance the entire stack, the top of the stack element exchange capacity of the reactor was continued for 1 minus balance

Step eight, continue to start from the last balance a non-leaf node, this time only two nodes 4 and 14, but does not meet the characteristics of the heap, we have to continue, 14 and 4 exchange, balance, top of the heap element exchange, Sort completion

Heap sort -9

Code

public class HeapSort {

    /**
     * 数组变动次数,只是为了记录
     */
    private static int time = 0;

    public static void sort(int[] arrays) {

        // 记录需要排序的数组长度,已经交换排好的部分需要排除
        int heapLength = arrays.length;

        // 循环堆化和交换的过程
        while (heapLength > 1) {
            // 1.将数组最大堆化
            maxHeapify(arrays, heapLength);
            System.out.println("数组堆化后:"+Arrays.toString(arrays));
            // 2.交换堆顶元素和最后一个元素,这样就排好了最后一个元素
            swap(arrays, heapLength);
            System.out.println("数组交换堆顶元素后:"+Arrays.toString(arrays));
            // 每次heapLength需减1
            heapLength--;
        }
    }

    private static void maxHeapify(int[] arrays, int heapLength) {

        // 从最后一个非叶子节点开始,最后一个非叶子节点 为 (heapLength >>> 1) - 1
        for (int i = (heapLength >>> 1) - 1; i >= 0; i--) {
            // 保存当前索引位置
            int currentIndex = i;
            // (currentIndex << 1) + 1 为当前节点左子节点索引
            // (currentIndex << 1) + 2 为当前节点右子节点索引
            int leftChildIndex = (currentIndex << 1) + 1;
            int rightChildIndex = leftChildIndex + 1;
            // 子节点中最大值的索引
            int maxChildIndex = -1;
            // 判断当前节点是否有子节点
            while (leftChildIndex <= (heapLength - 1)) {
                // 先赋值
                maxChildIndex = leftChildIndex;
                // 右子节点存在,则找子节点中的最大值
                if (rightChildIndex <= (heapLength - 1) && arrays[leftChildIndex] < arrays[rightChildIndex]) {
                    maxChildIndex = rightChildIndex;
                }
                if (arrays[maxChildIndex] > arrays[currentIndex]) {
                    // 和子节点交换当前索引值
                    int temp = arrays[currentIndex];
                    arrays[currentIndex] = arrays[maxChildIndex];
                    arrays[maxChildIndex] = temp;
                    time++;
                    System.out.println("数组第" + time + "次变动" + Arrays.toString(arrays));
                }
                // 继续判断交换后原子节点处是否满足堆的特性,直到当前节点下的局部二叉树完全满足堆的特性
                leftChildIndex = (maxChildIndex << 1) + 1;
                rightChildIndex = leftChildIndex + 1;
                currentIndex = maxChildIndex;
            }
        }
    }

    private static void swap(int[] arrays, int heapLength) {
        // 将最后一个数据与堆顶数据交换
        int temp = arrays[0];
        arrays[0] = arrays[heapLength - 1];
        arrays[heapLength - 1] = temp;
    }

    public static void main(String[] args) {
        int[] arrays = { 32, 4, 14, 56, 33, 78 };
        System.out.println("原数组:" + Arrays.toString(arrays));
        HeapSort.sort(arrays);
        System.out.println("排序后:" + Arrays.toString(arrays));
    }
}

operation result:

原数组:[32, 4, 14, 56, 33, 78]
数组第1次变动[32, 4, 78, 56, 33, 14]
数组第2次变动[32, 56, 78, 4, 33, 14]
数组第3次变动[78, 56, 32, 4, 33, 14]
数组堆化后:[78, 56, 32, 4, 33, 14]
数组交换堆顶元素后:[14, 56, 32, 4, 33, 78]
数组第4次变动[56, 14, 32, 4, 33, 78]
数组第5次变动[56, 33, 32, 4, 14, 78]
数组堆化后:[56, 33, 32, 4, 14, 78]
数组交换堆顶元素后:[14, 33, 32, 4, 56, 78]
数组第6次变动[33, 14, 32, 4, 56, 78]
数组堆化后:[33, 14, 32, 4, 56, 78]
数组交换堆顶元素后:[4, 14, 32, 33, 56, 78]
数组第7次变动[32, 14, 4, 33, 56, 78]
数组堆化后:[32, 14, 4, 33, 56, 78]
数组交换堆顶元素后:[4, 14, 32, 33, 56, 78]
数组第8次变动[14, 4, 32, 33, 56, 78]
数组堆化后:[14, 4, 32, 33, 56, 78]
数组交换堆顶元素后:[4, 14, 32, 33, 56, 78]
排序后:[4, 14, 32, 33, 56, 78]

The entire ordering process node change process has also been printed out on top, and the figure drawn before eleven confirmed, they would be tested under

A realization on Wikipedia as follows essentially the same, the reader may refer to the following:

public class HeapSort {

    /**
     * 堆排序数组
     */
    private int[] arrays;

    /**
     * 数组变动次数,只是为了记录
     */
    private static int time = 0;

    public HeapSort(int[] arrays) {
        this.arrays = arrays;
    }

    public void sort() {

        // 1.将数组堆化
        // 从第一个非叶子节点length >> 1 - 1开始,叶子节点不需要堆化调整
        // maxHeapify 调整index处及其子节点满足堆的特性
        int length = arrays.length - 1;
        for (int index = arrays.length >> 1 - 1; index >= 0; index--) {
            maxHeapify(index, length);
        }
        // 第一次初始化堆之后的数组:
        System.out.println("初始化堆后的数组:" + Arrays.toString(arrays));
        // 2.堆化数据排序
        // 先将已经堆化的数据堆顶数据(数组索引为0)与堆中最后一个元素交换
        // 交换完毕后对剩余节点重新堆化
        // 循环执行
        for (int i = length; i > 0; i--) {

            swap(0, i);

            System.out.println("交换堆顶元素后数组:" + Arrays.toString(arrays));

            maxHeapify(0, i - 1);
        }
    }

    private void maxHeapify(int index, int length) {

        // (index << 1) + 1 为当前节点左子节点索引
        // leftChildIndex + 1 为当前节点右子节点索引
        int leftChildIndex = (index << 1) + 1;
        int rightChildIndex = leftChildIndex + 1;
        // 子节点中最大值的索引,默认左子节点
        int maxChildIndex = leftChildIndex;
        // 左子节点已经超过堆化数组的长度,直接返回
        if (leftChildIndex > length) {
            return;
        }
        // 右子节点对应值比左子节点大,则替换maxChildIndex
        if (rightChildIndex <= length && arrays[rightChildIndex] > arrays[leftChildIndex]) {
            maxChildIndex = rightChildIndex;
        }
        // 判断是否需要交换
        if (arrays[index] < arrays[maxChildIndex]) {
            // 交换父子节点
            swap(index, maxChildIndex);

            // 这里主要是打印日志查看变化过程
            time++;
            System.out.println("数组第" + time + "次变动" + Arrays.toString(arrays));

            // 交换之后对子节点位置进行maxHeapify操作,使其保持堆特性
            maxHeapify(maxChildIndex, length);
        }
    }

    private void swap(int a, int b) {
        // 数组数据交换
        int temp = arrays[b];
        arrays[b] = arrays[a];
        arrays[a] = temp;
    }

    public static void main(String[] args) {
        int[] arrays = { 32, 4, 14, 56, 33, 78 };
        System.out.println("原数组:" + Arrays.toString(arrays));
        new HeapSort(arrays).sort();
        System.out.println("排序后:" + Arrays.toString(arrays));
    }
}

to sum up

Overall, heap sort is not very complicated, it is not hard to understand, a lot of new people could memorize the algorithm, is not necessary, first of all can be seen from the name of the most important is that the 'stack' word, when this sort when we think about the characteristics of this pile, remember that this feature can implement it yourself, it is important to understand that the process of its realization

Time complexity and space complexity I will not explain here, but this complexity is the need to find their own information to understand why this value is, after all, we use this algorithm is suitable for some scenes, the complexity of the analysis for us necessary

If you have questions please point out above, I will verify promptly corrected, thank you

Guess you like

Origin www.cnblogs.com/freeorange/p/11368736.html