2路归并指的是每次将集合分为2个子集和的归并排序。(此处用2分法)
归并排序原理是将现有集合划分为N个子集和,对N个子集和进行排序,再依次合并N个有序的子集和,直到最终合并成完整集合。
之前面试遇到一个经典的链表问题是合并两个有序链表,其实和归并中的并很相近。
归排和递归的快排写法相近,主要是合并函数merge的编写。
写法如下:
#include<iostream>
using namespace std;
int input[200];
void Merge(int first, int mid, int last) //合并
{
int len_left=mid-first+1; //mid左侧长度(包含mid)
int len_right=last-mid; //mid右侧长度
int *left = new int[len_left+1];
int *right = new int[len_right+1];
//根据mid把数组分为两部分(<=mid的和>mid的)
for(int i=0;i<len_left;i++) left[i]=input[first+i];
for(int i=0;i<len_right;i++) right[i]=input[mid+1+i];
//元素合并
int i=0,j=0,k=first;
while(i<len_left && j<len_right){
if(left[i] <= right[j]) input[k++]=left[i++]; //从小到大排列,则将小的先放入input
else input[k++]=right[j++];
}
while(i<len_left) input[k++]=left[i++]; //剩余元素合并
while(j<len_right) input[k++]=right[j++];
}
void merge_sort(int first, int last){
if(first<last){
int mid=(int)((first+last)/2); //二分
merge_sort(first,mid); //排序左侧
merge_sort(mid+1,last); //排序右侧
Merge(first,mid,last);
}
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>input[i];
merge_sort(0,n-1);
//输出排序结果
for(int i=0;i<n;i++) cout<<input[i]<<" ";
cout<<endl;
system("pause");
return 0;
}