The merge (merge) Sort method combines two (or more) ordered tables into a new ordered table. One disadvantage of merge ordering is that it requires the memory to have another array of size equal to the number of data items. If the initial array is almost full of memory, then the merge sort will not work, but if there is enough space, the merge sort is a good choice.
Suppose the sequence to be sorted:
4 3 7 9 2 8 6
First of all, the central idea of merging sort is to combine two sorted sequences into one sorted sequence.
The above sequence can be divided into:
4 3 7 9
And
2 8 6
The two sequences, and then sort the two sequences separately: the result is:
Set to sequence A, with sequence B,
3 4 7 9
2 6 8
Merge the top two sequences into a sorted sequence:
The specific ideas for merging are:
Sets two position indicators, pointing to the position where sequence A and sequence B start: Red is the indicator pointing position:
3 4 7 9
2 6 8
Compares the values of the elements pointed to by the two indicators and inserts the smaller into a new array, such as sequence C, while moving the corresponding indicator back one:
The results are:
3 4 7 9
2 6 8
The formation of the sequence C: has been inserted into an element, just a small element of 2.
2
Then compare sequence A with the element that the indicator in sequence B points to: Put the small into sequence C and move the corresponding pointer, and the result is:
3 4 7 9
2 6 8
2 3
And so on, the iteration executes until an indicator in sequence A or sequence B has been moved to the end of the array. For example:
After multiple comparisons, sequence B has moved the indicator out to the end of the sequence (after the last element).
3 4 7 9
2 6 8
2 3 4 6 7 8
Then there will be no use of the sequence, which is in sequence a the rest of the elements are inserted into the sequence of C, then there is a 9 left, inserted into the sequence C can be:
Sequence C Results:
2 3 4 5 6 7 8 9
This enables the operation of merging two ordered sequences into an ordered sequence,
Let's look at this merged PHP code:
/**
* Combines two ordered arrays into an ordered array
* @param $arrA, *
@param $arrB,
* @reutrn array combined with good arrays/
function Mergearray ($arrA, $arrB) {
$a _i = $b _i = 0;//Set two start position markers
$a _len = count ($arrA);
$b _len = count ($arrB);
while ($a _i< $a _len && $b _i< $b _len) {
//when array A and group B do not have boundaries if
($arrA [$a _i] < $arrB [$b _i]) {
$arrC [] = $arrA [$a _i++];
} else {
$arrC [] = $arrB [$b _i++];
}
}
Determine if the elements in array A are all used up, and if not, insert them all into the C array: while
($a _i < $a _len) {
$arrC [] = $arrA [$a _i++];
}
Determine if the elements in array B are all used up, and if not, insert them all into the C array: While
($b _i < $b _len) {
$arrC [] = $arrB [$b _i++];
}
return $arrC;
}
Through the above analysis and the implementation of the program, we are not difficult to find that the merging of sorted sequences should be linear, that is, the maximum occurrence of N-1 comparisons, where n is the sum of all elements.
With the above description, we have implemented the process of two sorted arrays.
At this point, you may have questions, what does this have to do with the whole sequence of merge sorting? Or how can you get the first two sorted subsequence?
Below, we'll describe what a merge sort is, and then look at how the relationship between merging and merging is sorted:
Let's just think, when we need to sort the array as follows, can we sort the first half of the array separately from the second half of the array, and then combine the results of the order?
For example: An array to be sorted:
4 3 7 9 2 8 6
Divide into 2 parts first:
4 3 7 9
2 8 6
Take the first half and the second half as a sequence and merge again (that is, split, sort, merge)
It will become:
Ago:
4 3
7 9
After:
2 8
6
Again, merge and sort each of the sequences again (split, sort, merge).
When there is only one element in the split subsequence (length 1), then the sequence does not have to be split, it is a sorted array. The sequence is then merged with other sequences, and eventually all of them are merged into a complete array of sorted arrays.
Program implementation:
By the above description, you should think that you can use a recursive program to implement this program:
To implement this program, you may need to address the following issues:
How to split an array:
Set two indicators, one pointing to the array is assumed to be $left, and one point to the last element of the array $right:
4 3 7 9 2 8 6
The
then determines whether the $left is less than $right, and if less than the number of elements in the sequence is more than one, split it into two arrays, split by generating an intermediate indicator $center, $left + $right/2 divisible. The result is: 3, then $left to $center into a group, $center +1 to $right into a group:
4 3 7 9
2 8 6
Next, the recursive use of $left, $center, $center +1, $right as the left and right indicators of two sequences, to operate. Know that there is an element in the array $left== $right. Then follow the merge array above:
/** * MergeSort Merge Sort * is the starting recursive function of a driver function * @param & $arr array to be sorted arrays/function MergeSort (& $arr) {$len = count ($
ARR)//Get array length Msort ($arr, 0, $len-1); /** * The program that actually implements the merge sort * @param & $arr Array * @param $left the lower left subscript of the int subsequence * @param $right the lower-right subscript of the int sequence * * function
Msort (& $arr, $left, $right) {if ($left < $right) {//Description There are more than 1 elements in the subsequence, you need to split, sort, merge//calculate the split position, length/2 to the whole
$center = Floor (($left + $right)/2);
Recursive calls to the left are sorted again: Msort ($arr, $left, $center);
Recursive calls to the right are sorted again Msort ($arr, $center +1, $right);
Merge sort results Mergearray ($arr, $left, $center, $right); }/** * Merges two ordered arrays into an ordered array * @param & $arr, all elements to be sorted * @param $left, sort sub array a start subscript * @param $center, sort the sub array A and the middle subscript of the sorted sub array b , that is, the end subscript * @param $right of the array A, the end subscript (starting as $center+1) of the sorted array b/function Mergearray (& $arr, $left, $center, $right) {//Set
Two starting position marks $a _i = $left;
$b _i = $center +1; while ($a _i<= $center && $b _i<= $right) {//when array A and Arrays B are not crossed out if ($arr [$a _i] < $arr [$b _i]) {$temp [] = $arr [$a _i++];
else {$temp [] = $arr [$b _i++];
}//Judge whether the elements in array A are all used up, and if not, insert them all into the C array: while ($a _i <= $center) {$temp [] = $arr [$a _i++];
//Judge whether the elements in array B are all used up, and if not, insert them all into the C array: while ($b _i <= $right) {$temp [] = $arr [$b _i++];
///$ARRC the sorted portions within the $arr: for ($i =0, $len =count ($temp), $i < $len; $i + +) {$arr [$left + $i] = $temp [$i];
}//do some test: $arr = Array (4, 7, 6, 3, 9, 5, 8);
MergeSort ($arr);
Print_r ($arr);
Note that the above code with the sorted array uses a reference pass, in order to save space.
Moreover, the way of merging the array is also to save space to do the relative modification, all the operations are placed on the $arr to complete, reference transfer to save resources.
All right, the code above completes the merge sort, the time complexity of the merge sort is O (N*logn) efficiency is quite objective.
Furthermore, the central idea of the merge sort algorithm is to decompose a complex problem into a similar small problem, and then decompose the small problem into smaller problems until it is decomposed into a method that can be solved immediately and then the results of the decomposition are merged. The idea is described as a "piecemeal" idiom. There is a major in computer science that is called divide-and-conquer strategy. The point is the big problem becomes small problem, cure is small result merge into big result.
The divide-and-conquer strategy is the basis of many funny algorithms, and we also use the partition strategy when we discuss fast sorting.
Finally, this algorithm is simple, although the algorithm reached O (NLOGN) in time complexity. But there's still a little problem, when merging two arrays, if the total number of elements in the array is N, then we need to open up a space of the same size to hold the merged data (that is, the $temp array in the Mergearray), and we also need to have $temp copies of the data to be $arr, Therefore, some resources will be wasted. Therefore, it is relatively less used in the actual sort.