5. heapsort)
Before getting started with "heap sorting", let's review the data structure C # Notes-tree and binary tree, which mentioned that "Full Binary Tree" has some important mathematical features:
It is a complete binary tree. If each node is numbered from top to bottom and from left to right, an array can be used to store the sequence number:
1. if I> 1, the parent nodule sequence number of I is I/2 (here/Refers to Division:The first half of the entire array is the parent node, and the last half is the leaf node.
2. If 2 * I <= N (here n is the total number of nodes in the entire tree), the left subnode with the serial number of I is 2 * I
3. If 2 * I + 1 <= N, the right subnode with the serial number of I is 2 * I + 1
Okay, let's see if heap is a magic horse?
In fact, the heap is a complete binary tree, which can be viewed from the knowledge point above. Given an array, we can construct it into a Complete Binary Tree, that is to say, create a "heap"-PS: Fortunately, the industry standard calls it a heap, instead of a pile :)
Heap can be dividedMax heapThe smallest heap is the largest heap:
In short, each (parent) node has a greater value than its subnode. Such a heap is called the largest heap. Likewise, if the value of each (parent) node is, smaller than its subnode, it is called the smallest heap.
The heapsort (heapsort) is launched below. The idea is as follows:
1. First, process the given array to be sorted to form a "Maximum Heap"
2. Swap the root node with the node (lastnode) of the last serial number so that the root node with the maximum value is, after "Sinking" to the end of all nodes (that is, the bottom), the next round of processing will ignore it.
3. Because of step 3, the remaining nodes cannot meet the definition of the maximum heap (because the last node with a small value is changed to the root node, its Sub-nodes will certainly have a value greater than it), and then process the remaining nodes in steps similar to step 1"
4. Repeat the operations in step 1 to compare the "root node of the new Max Heap" with the "Last node of the new Max Heap" (in fact, it is the second last node of the entire array, in the first round of processing, the maximum node has sunk to the end, so the last node of the new maximum heap is the last and second node of the entire array, in this way, the second largest element will sink to the appropriate position, and you will not need to worry about it later. Then, we will continue to recombine the remaining nodes into the largest heap.
5. Repeat the above process until there is only one remaining node (that is, there is no way to re-build the largest heap). At this time, the sorting ends, and the remaining node is definitely the smallest value.
If the new int [] {,} array is specified, the heap sorting is required.AlgorithmThe above algorithm is illustrated as follows:
After understanding the above ideas, heap sorting is split into two problems:
A. How to create a "Maximum Heap" for n elements in the specified range of arrays "?
B. How to use certain algorithms to repeatedly call the "Max heap creation" METHOD IN A to process the remaining nodes until only one element is left.
The algorithm for creating the largest heap relies entirely on the mathematical features of the Complete Binary Tree,CodeAs follows:
/// <Summary> /// create the maximum heap /// </Summary> /// <Param name = "arr"> arrays to be processed </param> /// <Param name = "low"> specify the lower subscript limit of the range of continuous elements to be processed </param> // <Param name = "high"> specify the upper subscript limit of the range of continuous elements to be processed </param> static void createmaxheap (INT [] arr, int low, int high) {If (low
Code that calls this algorithm to sort multiple times:
/// <Summary> /// heap sorting /// </Summary> /// <Param name = "arr"> </param> static void heapsort (INT [] ARR) {int TMP = 0; // during initialization, the entire array is arranged as "initial maximum Heap" createmaxheap (ARR, 0, arr. length-1); For (INT I = arr. length-1; I> 0; -- I) {// swap the root node with the last node TMP = arr [0]; arr [0] = arr [I]; arr [I] = TMP; // remove the elements from the background, and rearrange the remaining elements into "Max Heap" createmaxheap (ARR, 0, I-1 );}}
Comment: This is a unique way of thinking. The time complexity is similar to that of fast sorting. It is also related to binary trees, which are O (nlog2n). It is alsoUnstable.
6. Merge sort algorithm (mergesort)
Idea: think of each element in the array as a small sequence, and then combine the two into a new sequence of order (in this way, the number of sequences changes from N to n/2, but the length of each small sequence changes from 1 to 2), and then the new sequence is merged to obtain N/4 sequences (the length of each sequence changes from 2 to 4 ), after this repetition, a complete sequence is obtained. This is also one of the classic cases of "divide and conquer" in algorithms.
The processing of merging two sequences into a new sequence is used repeatedly here and encapsulated into the following methods:
/// <Summary> /// merge processing /// </Summary> /// <Param name = "arr"> array to be merged </param> // /<Param name = "len"> length of each small sequence </param> static void merge (INT [] arr, int Len) {int m = 0; // start position of the temporary sequence table int low1 = 0; // start position of the 1st ordered tables int high1; // The ending position of 1st ordered tables: int low2; // the starting position of the 2nd ordered tables: int high2; // The ending position of the 2nd ordered tables: int I = 0; int J = 0; // temporary table, used to temporarily merge two ordered tables into an ordered table int [] TMP = new int [arr. length]; // merge processing while (low1 + Len) <arr. lengt H) {low2 = low1 + Len; // the starting position of the first 2nd ordered tables high1 = low2-1; // The end position of 1st ordered tables // The end position of 2nd ordered tables high2 = (low2 + len-1) <arr. length )? Low2 + len-1: arr. length-1; I = low1; j = low2; // if the two sorted tables are not complete while (I <= high1) & (j <= high2) {If (ARR [I] <= arr [J]) // if the number of elements in the 1st ordered tables is smaller than the number of corresponding elements in the 2nd ordered tables, then, directly copy the elements of the 1st ordered tables to the temporary table {TMP [M ++] = arr [I ++];} else // otherwise, copy the elements of the first ordered table to the temporary table {TMP [M ++] = arr [J ++] ;}// after processing, if the first ordered table contains the element while (I <= high1) {TMP [M ++] = arr [I ++] ;}// after processing, if there are still elements in the 2nd ordered tables while (j <= high2) {TMP [M ++] = arr [J ++];} low1 = high2 + 1; // After the low1 "Pointer" refers to "two processed ordered tables", it is convenient to copy the remaining unprocessed elements to the temporary table} I = low1; // copy unprocessed elements to the temporary table while (I <arr. length) {TMP [M ++] = arr [I ++];} // copy the elements of the temporary table to the original array for (I = 0; I <arr. length; ++ I) {arr [I] = TMP [I] ;}}
Sorting:
/// <Summary> /// merge sort /// </Summary> /// <Param name = "arr"> </param> static void mergesort (INT [] ARR) {int K = 1; // merge incremental while (k <arr. length) {merge (ARR, k); K * = 2 ;}}}
Comments: The merger is related to 2. Haha, the computer field is really 2! Therefore, the time complexity is O (nlog2n), but this algorithm requires a lot of temporary arrays, so its space complexity is greater than that of other algorithms ), in addition, it is a stable sorting method.
Summary of sorting method: (the summary of the original book is not good, so I am too lazy to write it again, and copy it from the original e-book to record it)
Sort in ComputerProgramThe design is very important. The sorting methods described above have their own advantages and disadvantages, and their application scenarios are also different.
The following factors should be taken into account when selecting the sorting method:
(1) The size of N, the number of records to be sorted;
(2) The amount of information except the key code recorded;
(3) key code (that is, element value;
(4) Requirements for sorting stability;
(5) conditions of language tools, sizes of auxiliary space, and so on.
Based on the above factors, we can draw the following conclusions:
(1) If the number of sorting records is less than or equal to n (for example, n ≤ 50), you can directly insert or simply select sorting. Because the moving operation of records required for direct insertion and sorting is easier to select and sort, it is better to simply select and sort records when the information volume of records is large.
(2) If the initial status of the record has been sorted by the key code, you can sort it by direct insertion or bubble.
(3) If the number of sorting records is N, the time complexity is O (nlog2n) (such as fast sorting, heap sorting, or Merge Sorting ).
The average performance of quick sorting is the best. It is the most suitable for fast sorting when the sequence to be sorted has been randomly distributed by key code. In the worst case, the time complexity of quick sorting is O (n2), while in the worst case, the time complexity of heap sorting does not change, and the required auxiliary space is less than the quick sorting. However, these two sorting methods are not stable. If a stable sorting method is required, Merge Sorting can be used.
(4) The sorting algorithms discussed earlier use the sequential storage structure. When there are many records to be sorted, a chain storage structure can be used to avoid the large amount of time to move the records. Direct insertion sorting and Merge Sorting can be easily implemented on the linked list, but fast sorting and heap sorting are difficult to implement on the linked list. In this case, you can extract the key code to create an index table and then sort the index table. You can also introduce an integer array T [N] as a secondary table. Before sorting, t [I] = I, 1 ≤ I ≤ n. If the sorting algorithms require the exchange of records R [I] and R [J], only T [I] and T [J] are required. After sorting, the array T [N] stores the sequential relationship between records.