Total Solution of merge order (including complexity proof)

Source: Internet
Author: User
Merge Sort 1. Introduction to merge Sort:Merge ordering is a sort algorithm based on multiple recursion, is a kind of effective sorting algorithm based on merging operation, which is a typical use case of partition method, because it adopts the partition rule and is a two-way branch, (we also call it two-way merging), So the recursive tree of the merge sort is always balanced, at which point the merge sort has obvious advantages over the quick sort (but actually because the concept of cache is involved, the actual algorithm of merging sort is slower than fast sorting), On this I refer to a large number of blogs and snub forums but all see no quick sort, merge sort, heap sort, hill sort of real apprehension, and the immediacy of shame
because we are merging the sub arrays exactly in the order of the array from left to right, so that the merge sort is stable sort
Merged sort of recursive tree drawings:

Advantages: Merge sort only deals with adjacent array elements, so the rate of merge ordering is likely to be better than the ordinary fast-row disadvantage in a data volume region: Merge sort takes up a lot of memory space ( occupies a space of the same length as the original array, which is a completely fatal disadvantage once the amount of array is very large ., so the merge sort can easily overflow the memory when it is large data.
2. Algorithm Explanation:The whole explanation of the algorithm: we pass through the constant recursion, until the data length of each segment is itself, we automatically assume that we have reached our so-called ordered state at this time, and then we do the selective insertion sort, in which the complexity is just the size of the length we traverse, that is, O (n), So it's very efficient (but realize that we're using space to change time to optimize)
In the whole structure of the algorithm, we can divide the whole algorithm into two pieces to consider the first block of code: just mentioned, to each adjacent to take the insertion just mentioned the second block of code snippet: multiple recursion, when it reaches our recursive termination conditions (each paragraph has only one element, the default order), The merge operation of backtracking
The complexity of the algorithm proves: because the merge sort algorithm is binary, so the division naturally has the following proof:
T (n) =2t (N/2) +f (n)  Note that the consideration of f (n) here is from the back forward, since the advantages of merge sorting are similar to the subsequent traversal of binary trees, f (n) is said to represent the merging operation of the recursive tree of each layer, so f (n) is an O (n)
T (n) =4t (n/ 4) +2f (n)
... log2n=k, a total of K-layer recursion 

3. The implementation of the algorithm:C + + code class encapsulation: (I will explain in more detail in the code)
#include "iostream" #include "Cstdio" #include "cstdlib" #include "CString" #define N #define INF 99999999 using NAMESPA

CE std;
Template<typename t> class MergeSort;
Template<typename t> istream& operator>> (istream&,mergesort<t>&);

Template<typename t> ostream& operator<< (ostream&,mergesort<t>&); Template<typename t>//need to extend O (n) space complexity to implement sort operations class MergeSort {Public:mergesort () {memset (data,0,sizeof
			(data));
		num=0;
		Friend istream& operator>><> (istream&,mergesort<t>&);
		Friend ostream& operator<<<> (ostream&,mergesort<t>&);
		void Premerge () {merge_sort (1,num);
		} void Merge_sort (Int,int); 
	void Mergearray (Int,int,int);
		Private:t Data[n];
int num;

}; Template<typename t> istream& operator>> (istream& in,mergesort<t>& k) {cout<< " Please input the number of the data!
	<<endl;cin>>k.num;
	for (int i=1;i<=k.num;i++) cin>>k.data[i];
return in; } template<typename t> ostream& operator<< (ostream& out,mergesort<t>& k) {cout<< "
	The results of the order are as follows: "<<endl;
	for (int i=1;i<=k.num;i++) cout<<k.data[i]<< ';
	cout<<endl;
return out;
	} template<typename t> void mergesort<t>::merge_sort (int left,int right) {if (left>=right) return;
	int mid= (left+right)/2;
	Merge_sort (Left,mid);
	Merge_sort (Mid+1,right);
	Mergearray (Left,mid,right);
return;
	} template<typename t> void mergesort<t>::mergearray (int left,int center,int right) {int n1=center-left+1;
	int n2=right-center;   T s1[n1+2];
	Starting from 1, and the last element is set to monitor (although this will increase the complexity of the space to O (N+LOGN) but good implementation) T s2[n2+2];
	int j=1;
	for (int i=left;i<=center;i++,j++) s1[j]=data[i];
	J=1;
	for (int i=center+1;i<=right;i++,j++) s2[j]=data[i];
	int i=1;j=1;   S1[n1+1]=s2[n2+1]=inf;
monitoring whistle for (int k=left;k<=right;k++)//insert Sort Process {		if (S1[i]<s2[j]) data[k]=s1[i++];
	else data[k]=s2[j++];
	int main () {mergesort<int> my1;
	Mergesort<double> My2;
	cin>>my1>>my2;
	My1.premerge ();
	My2.premerge (); 
	cout<<my1<<my2<<endl;
return 0; }

4. Merge sort application: 4.1 Merge sort to find maximum reverse logarithmWe know that one way to get the maximum number of reverse logarithms is to sweep through them from beginning to end, and the complexity of the time is:
T (n) =1+2+...+n-1=o (n*n)
But by merging the sort we can optimize the time complexity of the method to O (N*LOGN)
Ideas are as follows: We can find that, in the merging backtracking process, our previous array is always ordered, and the latter is always in order (only the latter is ordered, we begin the next merge) when the latter group is ordered, we begin to merge, As we continue to insert, if we discover that an element in the previous paragraph is larger than an element in the latter paragraph, then the element to the end of the previous array of elements satisfies the same state, then the solution of the sub array will be greatly accelerated but some people will ask, is this not repeated calculation, The big man won't, because we are considering it for a period of time: this is a paragraph of this understanding, the previous element and the last element of the inverse of the relationship between the pairs of relations (number) is not with the first paragraph of the order and the next paragraph of the sort index entry, we previously calculated the previous paragraph between the logarithm of the sequence is small, After we have constantly expanded its scope to judge, is exactly the right way
And some people may ask, then can only record not sort it, this will not be able to optimize the complexity of the time: here, we can only say a little whimsical, our considerations are based on the previous subset of the array and the order of the last array of cases to consider, so that ordering is an essential part, Only a sort can we simplify the cumulative computation of repeated traversal into the mathematical expression calculation of O (1) in an orderly manner (note below)
Attached code: (in the same place just to make a small change)
#include "iostream" #include "Cstdio" #include "cstdlib" #include "CString" #define N #define INF 99999999 using NAMESPA

CE std;
Template<typename t> class MergeSort;
Template<typename t> istream& operator>> (istream&,mergesort<t>&);

Template<typename t> ostream& operator<< (ostream&,mergesort<t>&); Template<typename t>//need to extend O (n) space complexity to implement sort operations class MergeSort {Public:mergesort () {memset (data,0,sizeof
			(data));
			num=0;
		ans=0;
		Friend istream& operator>><> (istream&,mergesort<t>&);
		Friend ostream& operator<<<> (ostream&,mergesort<t>&);
		void Premerge () {merge_sort (1,num);
		} void Merge_sort (Int,int);
	void Mergearray (Int,int,int);
		Private:t Data[n];
		int num;
int ans;

}; Template<typename t> istream& operator>> (istream& in,mergesort<t>& k) {cout<< " Please input the number of the Data! "
	<<endl;
	cin>>k.num;
	for (int i=1;i<=k.num;i++) cin>>k.data[i];
return in; } template<typename t> ostream& operator<< (ostream& out,mergesort<t>& k) {cout<< "
	The results of the order are as follows: "<<endl;
	for (int i=1;i<=k.num;i++) cout<<k.data[i]<< ';
	cout<<endl<< "The reverse logarithm is:" <<k.ans<<endl;
return out;
	} template<typename t> void mergesort<t>::merge_sort (int left,int right) {if (left>=right) return;
	int mid= (left+right)/2;
	Merge_sort (Left,mid);
	Merge_sort (Mid+1,right);
	Mergearray (Left,mid,right);
return;
	} template<typename t> void mergesort<t>::mergearray (int left,int center,int right) {int n1=center-left+1;
	int n2=right-center;   T s1[n1+2];
	Starting from 1, and the last element is set to monitor (although this will increase the complexity of the space to O (N+LOGN) but good implementation) T s2[n2+2];
	int j=1;
	for (int i=left;i<=center;i++,j++) s1[j]=data[i];
	J=1;
	for (int i=center+1;i<=right;i++,j++) s2[j]=data[i];
	int i=1;j=1; S1[n1+1]=s2[n2+1]=inF
		monitoring whistle for (int k=left;k<=right;k++)//Insert Sort Process {if (S1[i]<=s2[j]) data[k]=s1[i++];
			else//satisfies the reverse order condition {data[k]=s2[j++];    ans+=center-left+1-i+1;
	This is the part of the above explaining the} {main () {mergesort<int> my1;
	Mergesort<double> My2;
	cin>>my1>>my2;
	My1.premerge ();
	My2.premerge (); 
	cout<<my1<<my2<<endl;
return 0; }

4.2 Find the maximum sub array and (O (N*logn)) (the next post will again introduce O (n) dynamic programming idea solution)Dynamic Programming Solution
First of all, I enclose this blogger for a few months before the division of the maximum sub-array explanation
First of all, we have to make it clear that the maximum word group will only have three cases 1. All on the left half 2. All on the right half 3. Across the left and right (when calculating we start with the emphasis on both sides) Then we divide the method (merge) The idea is each time by solving the upper layer of the largest sub array to return its value to find the maximum value of this layer, the last three (discussed above) comparison is good. Enclose the code in C + + package:
#include "iostream" #include "cstdlib" #include "Cstdio" #include "CString" #define N #define INF-99999999 using Namespa

CE std;

Template<typename t> class Submax;
Template<typename t> class Submax;
Template<typename t> istream& operator>> (istream&,submax<t>&);

Template<typename t> ostream& operator<< (ostream&,submax<t>&);
			Template<typename t> class Submax {Public:submax () {memset (data));
		num=ans=0;
		Friend istream& operator>><> (istream&,submax<t>&);
		Friend ostream& operator<<<> (ostream&,submax<t>&);
		void Premerge () {ans=merge (1,num);
		T merge (Int,int);
	T Submaxcross (Int,int,int);
		Private:t Data[n];
		int num;
T ans;

}; Template<typename t> istream& operator>> (istream& in,submax<t>& k) {cout<< " 
	Please enter the number of your array: ";cin>>k.num; cout<< "Please input your array" &LT;&LT;endl;
	for (int i=1;i<=k.num;i++) cin>>k.data[i]; 
return in; } template<typename t> ostream& operator<< (ostream& out,submax<t>& k) {cout<< "
	The sum of the maximum sub array of the array you entered is: "<<k.ans<<endl; 
return out;
	} template<typename t> T submax<t>::merge (int left,int right) {if (left>=right);
		else {T leftsum=inf;
		T Rightsum=inf;
		T Crosssum=inf;
		int mid= (left+right)/2;
		Leftsum=merge (Left,mid);
		Rightsum=merge (Mid+1,right);
		Crosssum=submaxcross (Left,mid,right);
		if (leftsum>rightsum&&leftsum>crosssum) return leftsum;
			else {if (rightsum>leftsum&&rightsum>crosssum) return rightsum;
		else return crosssum;
	}} template<typename t> t submax<t>::submaxcross (int left,int mid,int right) {T leftsum=inf;
	T Rightsum=inf;
	T sum=0;
		for (int i=mid;i>=left;i--) {sum+=data[i];
	if (sum>leftsum) leftsum=sum;
	} sum=0; for (int i=mid+1;i<=right;i++) {Sum+=data[i];
	if (sum>rightsum) rightsum=sum;
return leftsum+rightsum;
	int main () {submax<int> my1;
	Submax<double> My2;
	cin>>my1>>my2;
	My1.premerge ();
	My2.premerge ();
	cout<<my1<<my2<<endl;
return 0; }



5. Merging sort of space complexity optimization thinking (merge in situ)First attached to the reference: this blogger in situ merge algorithm full explanation + hand-cranked algorithm
http://blog.csdn.net/hitxueliang/article/details/7542607
Http://www.92to.com/bangong/2016/06-30/6929855.html
6. Thinking Questions:1. How to record the maximum sub array 2. Or not fully understand the principle of in situ merging (hand algorithm) This problem has been resolved 3. Still do not understand why merge relatively fast row for slow, cache in the end where the impact. 7. Reference documents:http://blog.csdn.net/shawn_hou/article/details/38059701
Http://zhidao.baidu.com/link?url=GbttGQ8bg-l2AlT7A-uibWXyLBDDhnmLETC1w2fsOc_ Jsc6jde-jw01d8dvjtc757ug9vjvycejyadad1ycli5zrmzixh81aczuuxzrwoqi
http://blog.csdn.net/morewindows/article/details/6678165/

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.