[Algorithm learning] heap sorting)

Source: Internet
Author: User

Heap sorting introduces another algorithm design technology: using a certain data structure (In this algorithm, it is "heap") to manage information in Algorithm Execution.

I. HeapHeap Introduction

We usually use the binary heap of the heap. It is an array object and can be considered as a Complete Binary Tree. Each node in the tree corresponds to the node in the array. As shown in:

The heap array usually consists of two attributes: the length of the number of elements in the array [a], and the number of heap-size elements stored in a [A]. That is to say, some elements stored in a may not belong to the corresponding heap. Therefore:

Heap-size [a] <= length [A].

Given the subscript I of a node, the parent node, the left son, And the right son can be easily calculated:

Note: The subscript starts with 1 instead of 0.

Parent node: parent (I) = floor (I/2) (rounded down)

Left son: Left (I) = 2 * I

Right son: Right (I) = 2 * I + 1

Heap Classification

A binary heap is usually divided into a large heap and a small heap.

In a large root heap, for a subtree with a node as the root, the value of each node is not greater than the value of its root node, that is, a [Parent (I)]> = A [I]

The opposite is true for the small root heap.

In heap sorting, we use a large heap (from small to large ). The small root heap is usually used in the STL priority queue.

Heap height

The height of a node in the heap is defined as the number of edges in the longest simple descent path from the node to the leaf.

The height of the heap is the height of the root node.

Ii. Heap Adjustment

Most of the time, a binary tree does not satisfy the nature of a large root heap. We need some algorithm to adjust it to make it into a large root heap. The following function maxheapify will implement this function. We assume that the subtree with the left son node and the right son node as the root of a node I is a big root heap, but a [I] may be less than the value of its child node, this violates the nature of the big root stack.

General idea of the algorithm:

First, find the node with the largest median value between the I node and Its left and right subnodes. If it is not I, swap the node with the largest I value. This ensures that the value at root I is the largest. Then adjust the subtree rooted in the subnode that is just swapped with I, and call the maxheapify algorithm recursively.

Algorithm CPP Code implementation:

// Obtain the parent node index int getparent (int I) {return (INT) floor (float) I/2);} // obtain the left subtree index int getleftson (int I) {return (2 * I);} // get the right subtree index int getrightson (int I) {return (2 * I + 1 );} // adjust the subtree with a node I as the root node as the big root heap void maxheapify (int A [], int I, int heapsize) {int left = getleftson (I ); int right = getrightson (I); int largest = I; // index of the element with the highest record value if (left <= heapsize & A [left]> A [I]) {largest = left;} If (right <= heapsize & A [right]> [Largest]) {largest = right;} If (largest! = I) // This subtree does not meet the nature of the big root heap and needs to be adjusted {// For int temp = A [I]; A [I] = A [Largest]; A [Largest] = temp; maxheapify (A, largest, heapsize); // recursive call, continue to adjust the subtree }}

Heap Adjustment Example

Time Complexity Analysis:

Adjust the time of a [I], a [left], and a [right] to a constant time.

The following analyzes the time required to recursively adjust the subtree with a subnode of I as the root.

If the number of nodes in the tree is N, the number of subtree nodes in the I node is 2n/3 at most (when the bottom layer is half full, it is obtained by the full Binary Tree ),

Derivation process:

Total number of nodes in the tree

N = POW (2, 0) + POW (2, 1) +... + POW (2, h-1-1) + 1/2 * POW (2, h-1), where H is the height of the tree (the root layer is the first layer)

= 3 * POW (2, H-2)-1

Assume that the number of subtree nodes corresponding to the left son of the root node is greater than that of the right subtree. The height of the node is h-1, and the number of nodes is:

Pow (2, 0) + POW (2, 1) +... + POW (2, h-1-1) = POW (2, h-1)-1
In combination with the preceding formula, the maximum number of nodes in the subtree is (2 * n-1)/3.

In this way, the estimated time complexity of the heap is adjusted:

T (n) <= T (2n/3) + O (1)

Recursive Formula: T (n) = O (lgn ). Or O (h), H is the height of the tree.

3. Heap BuildingHeap construction ideas

We can call the above-mentioned method to adjust the heap maxheapify from the bottom up to change an array to the largest heap.

Note: The Sub-array a [floor (n/2) + 1]... A [n] is the leaf of the tree. Obviously, the leaves can be regarded as a large pile with only one element without adjustment. You only need to adjust the number of non-leaf nodes from the back to the back.

Heap creation example

Example of creating a heap:

The last non-leaf node is 2, so the adjustment function is called in sequence from 2.

C ++ code implementation:

// Heap creation void buildmaxheap (int A [], int heapsize) {for (INT I = (INT) floor (float) heapsize/2); I> 0; -- I) {maxheapify (A, I, heapsize) ;}cout <"built big root heap:" <Endl; printheap (A, heapsize );}

Time Complexity Analysis

A height with N element Stacks is floor (lgn), and there are multiple Ceil (N/POW (2, H + 1) nodes at any height H.

In this way, the time complexity is calculated as follows:

The sum on the right can be calculated as follows:

Sub-statement:

The result is as follows:

, So there are:

Therefore, the time complexity of heap building is as follows:

That is, an unordered array can be built into a large heap in linear time.

Iv. Heap sortingAlgorithm IDEA

The first is to build an unordered array into a large root heap, and then swap the largest element, that is, the root with a [n], so that the maximum element reaches the correct position.

Then remove node N from the heap. The child of the original root is still a big root heap, but the new root element may violate the rules of the big root heap, you must re-adjust a [1 ,..., n-1] is a large heap. This is repeated. It does not end until the heap size changes to 1.

Heap sorting example

C ++ code implementation:

// Heap sorting void heapsort (int A [], int heapsize) {buildmaxheap (A, heapsize); For (INT I = heapsize; I> 0; -- I) {int temp = A [1]; A [1] = A [I]; A [I] = temp; maxheapify (A, 1, I-1 );}}

Time Complexity Analysis

The time complexity of heap sorting is O (nlgn ). The heap time is O (n ). Adjust the heap for n-1 times. The cost of each time is O (logn ).

In addition, it is an in-situ sorting algorithm, that is, in the array at any time, only a constant element is stored in the input array.

Program instance:

# Include <iostream> # include <cmath> using namespace STD; // Note: The following table starts with 1 instead of 0. // you can obtain the parent node index int getparent (int I) {return I> 1;} // get the left subtree index int getleftson (int I) {return I <1 ;} // obtain the right subtree index int getrightson (int I) {return (I <1) + 1 );} // adjust the subtree with a node I as the root node as the big root heap void maxheapify (int A [], int I, int heapsize) {int left = getleftson (I ); int right = getrightson (I); int largest = I; // index of the element with the highest record value if (left <= heapsize & A [left]> A [I]) {lar Gest = left;} If (right <= heapsize & A [right]> A [Largest]) {largest = right;} If (largest! = I) // This subtree does not meet the nature of the big root heap and needs to be adjusted {// For int temp = A [I]; A [I] = A [Largest]; A [Largest] = temp; maxheapify (A, largest, heapsize); // recursive call, continue to adjust the subtree} // output array element void printheap (int A [], int heapsize) {for (INT I = 1; I <= heapsize; ++ I) {cout <A [I] <";}cout <Endl ;}// heap creation void buildmaxheap (int A [], int heapsize) {for (INT I = (INT) floor (float) heapsize/2); I> 0; -- I) {maxheapify (A, I, heapsize );} cout <"built big root heap:" <Endl; printheap (A, heapsize);} // heap sorting void heapsort (int A [], int heapsize) {buildmaxheap (A, heapsize); For (INT I = heapsize; I> 0; -- I) {int temp = A [1]; A [1] = A [I]; A [I] = temp; maxheapify (A, 1, I-1) ;}} int main () {const int length = 11; // The heap element starts from 1 to get off work. int A [length] = {, 7 }; int heapsize = length-1; heapsort (A, heapsize); cout <"after heapsort:" <Endl; printheap (A, heapsize );}

Running result:

V. Application of heap sorting

Heap sorting is widely used:

(1) priority queue in STL.

(2) Search for the K number or the maximum K number. For details, see the beauty of programming.

For example, in massive data processing, the maximum number of data records is 0.1 billion.

This policy can also be used to improve efficiency when building a user-defined tree. We need to select two smallest elements from the set each time, then add the elements and combine them into a new element. We can heap to improve efficiency.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.