Heap Sort
In the heap sort, we can consider the order table as a complete two-fork tree
Binary Tree Knowledge Review:
Numbering each node in the two-fork tree starting with 1
Sequence: [#, C, H, G, E, A, D, I, F, B, K]
Index 1 2 3 4 5 6 7 8 9 10
So the left child with number I is numbered 2*i, and the right child node number is 2*i+ 1,
In addition to the root node, if a node is numbered J then the parent node is J//2
If the sequence R[1,n] is regarded as a complete binary tree, then R[i's left child is r[2i] the right child is r[2i+1]
Heap:
N-value Sequence k[1],k[2],k[3] ... K[n] called the heap.
The sequence satisfies the attributes
Dagen: K[i] >= k[2*i] and k[i] > = k[2*i +1] I range 1 ~ N//2
Small Gan: K[i] <= k[2*i] and K[i] <= k[2*i +1]
As shown in the figure
Little Gan
Dagen
The simple process of heap sorting is:
1, according to the sequence, build an initial heap (Dagen/Keng Gen)
2, the first and last element of the swap heap.
3, excluding the last element, the sequence first to the penultimate second to rearrange the stack.
4, swap the first and last elements of the heap again
5. Repeat the 3rd step
6, repeat the above process until the completion of the order
The simple point is: Construct heap, exchange element, construct heap, exchange element, construct heap ...
From the third step of the 6 steps above, swap the first and last elements, and the action repeats every time the heap is sorted out. So we know that the last element of the sequence is always the largest/smallest element of the current heap. So, the first step, whether we're going to build a Dagen or a little Gan, is to see if we're going to sort the sequence sequentially or in reverse order.
In the example below we sequence the sequence, which means building a large heap.
Have such a sequence
A = [–, 1, 0, 3, 6, 2, 8, 4, 9, 7, 5]
Constructs a binary tree in which the tree nodes are numbered starting from 1. So a[0] is a placeholder. The initial binary tree is as follows:
Start building large piles.
1, starting from the last non-leaf node. Compare the node and its maximum child node, if the node is large, then remain unchanged. If the child node is large, swap the child node and the value of the node.
In this case, the last non-leaf node is a node with an ordinal number of 5 and a value of 2. Compare it and its largest child node. Found 5 >2 so exchanged him and his children.
2, and then look at the last and second non-leaf node, which is the number 4 value 6 node. The same compares it with its largest child node. Found that 6<9 also need to exchange [the red part of the following image]
3, and then continue to look at the last and third non-leaf node, that is, the serial number 3 is 3 of the node, also compare it and its largest child node, found 8>3, also need to exchange [the gray part of the following figure]
4, and then continue to compare the bottom fourth non-leaf node. A node with an ordinal number of 2 values of 0. Compare it with its largest child node, find 0<9, swap 2 ... Don't worry, you'll see that even if 0 and 9 are switched, 0 is smaller than its current maximum child node (7), so continue swapping 0 and 7. The final result is the following figure:
5, then move the serial number 1, the value is 1 node ... Repeating the above process, the final structure of the large root heap is as follows:
This is the process of completing the construction of the initial heap. The functions are as follows:
Def Fixdown (A, I, N): # I means the current node n is the maximum index for all elements in the sequence. The ordinal of the last node in the binary tree while
2 * I <= N: # j = 2*i is the left child of the current node. It must be within the ordinal range of all nodes. If J > n are indicated i is a leaf node.
j = 2 * I
if J < N and A[j] < A[j + 1]: # Choose the bigger one in the children's node. Note one: The following details.
J + 1
if a[i] < A[j]: # If the parent node is smaller than the child node, then swap the parent and child nodes. The position of I is moved down at the same time. The range of I is [1-N//2]
a[i], a[j] = A[j], a[i]
i = j
Else: #如果双亲节点大于他的最大的孩子, then this small two-fork tree build heap is completed. Break
View Code
Note One: The short circuit principle is used in this statement. That is, if J < n is false then the following conditions will no longer be judged. Skip the conditional statement directly and proceed to the following statement. Why do I require J!= N in this conditional statement, in this case j = 10, if the conditional statement is changed to j<= N, <=10, and the first condition is set up, then it will undoubtedly continue to verify that the second condition is set up, whereas in this case you will find that there is no 11th node, that is a[j+1] is not there. So this will cause a program to throw an error that exceeds the index.
To initialize the heap, and also to organize the heap, the next step is to call the function in the main function of the heap sort, to sort the heap, or to show the code in the diagram first.
Review the process of heap sequencing described above. The construction heap is complete, so it is time to swap the first node and the last node. Then, the last node is excluded and the heap is built again with the remaining nodes.
Reconstruct the heap as follows:
Swap the first and last one as follows:
Repeat the above process until there is no node to build the heap. Sorting completed.
The code is as follows:
Def heapsort (a):
n = Len (a)-1 # because a placeholder element is added, the actual number of elements in the build heap should be subtracted from 1 for
I in range (n//2, 0,-1): #构建初始堆. Start the build heap from the last non-leaf node. Floor except 1 is to prevent the occurrence of decimal, 2 is to take the lower bound.
Fixdown (A, I,n) # invokes the function of the constructor heap above to construct the initialization heap.
print (' a= ', A) #这里可以看一下 The order of the elements of the sequence after the initialization heap while
n > 1: # N represents the serial number of the last node of the heap
a[1], a[n] = A[n], a[ 1] # Exchange Heap of the first and last nodes
Fixdown (A, 1, n-1) # Rearrange the remaining nodes of the heap, build Gan
N-= 1 # after each Exchange, The sorted nodes are excluded from the heap, so the last node of the heap moves forward one bit.
return a[1:] #因为我们使用了占位元素, so returns elements from so 1 and beyond.
a = ['--', 1, 0, 3, 6, 2, 8, 4, 9, 7, 5] # The first element does not need to occupy the position
Print (Heapsort (A))
View Code
Here again:
Because we are from small to large permutation sequence. So each time let A[i be compared to the larger one in his sub node, then the big float and the small sinking. Thus building large piles
If we want to order from big to small,
Then let the a[i] compare with the smaller of its child nodes, the smaller floats, the larger sinks.
So the code for the construction heap is as follows:
Def Fixdown (A, I, N): # I means the current node n is the maximum index for all elements in the sequence. The ordinal of the last node in the binary tree while
2 * I <= N: # j = 2*i is the left child of the current node. It must be within the ordinal range of all nodes. If J > n are indicated i is a leaf node.
j = 2 * I
if J < n and A[j] > a[j + 1]: # Select the left and right children node more ... Small.. that
j + + 1
if a[i] > A[j]: # If the parent node. Greater than.. child node, then swap the parent and child nodes. The position of I is moved down at the same time. The range of I is [1-N//2]
a[i], a[j] = A[j], a[i]
i = j
Else: #如果双亲节点. Less than.. He's.. Minimum.. Child, then this small two-fork tree build heap completes. Break