归并排序是几种排序算法中较快的一种,速度快,稳定性高,因为经常使用,下边就详细讲解一下
归并排序才用了分治的思想,将数进行的分组,分割到最小组,然后进行合并,合并时排序(个人理解),直到完成排序。但是归并排序需要占用额外的空间。
- 代码如下:
- C++实现:
#include<cstdio>
#include<cstring>
#define MAXN 7000
using namespace std;
Merge_Array(int* arr,int l,int m,int r,int* p) //将数组进行合并
{
int i=l,j=m+1; //数组中,l-m为左半边的数,而m+1 ->r为右半边的数,合并到临时数组p种
int pc=0;
while(i<=m && j<=r)
{
if(arr[i]<=arr[j]) p[pc++]=arr[i++];
if(arr[i]>arr[j]) p[pc++]=arr[j++];
}
while(i<=m) p[pc++]=arr[i++];
while(j<=r) p[pc++]=arr[j++];
for(i=0;i<pc;i++)
arr[i+l]=p[i]; //每次合并后,前l项已经排完
}
merge_sort(int* arr,int l,int r,int* p) //进行分治,直到最小组为止
{
if(l<r)
{ //这个过程主要采用递归,递归利用了栈,考虑到栈的LIFO特性,就不难以理解
int m=(l+r)/2;
merge_sort(arr,l,m,p); //进行左边分治
merge_sort(arr,m+1,r,p); //进行右边分治
Merge_Array(arr,l,m,r,p); //归并 && 排序
}
}
void Merge_sort(int* arr,int n) //这里是新开辟了临时的数组,也可以使用全局变量,这个可有可无
{
int *p=new int[n];
merge_sort(arr,0,n-1,p);
delete p;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
int arr[MAXN];
for(int i=0;i<n;i++)
scanf("%d",&arr[i]);
Merge_sort(arr,n);
for(int i=0;i<n;i++)
printf("%3d",arr[i]);
printf("\n");
}
}
- Java代码(没有注释)
import java.util.Scanner;
public class merge_sort {
static int[] p=new int[4000];
public static void Merge_Array(int[] arr,int l,int m,int r,int[] p){
int i=l,b=m+1;
int pc=0;
while(i<=m && b<=r){
if(arr[i]<=arr[b]) p[pc++]=arr[i++];
if(arr[i]>arr[b]) p[pc++]=arr[b++];
}
while(i<=m) p[pc++]=arr[i++];
while(b<=r) p[pc++]=arr[b++];
for(i=0;i<pc;i++){
arr[l+i]=p[i];
}
}
public static void merge_sort(int[] arr,int l,int r,int[] p){
if(l<r){
int m=(l+r)/2;
merge_sort(arr,l,m,p);
merge_sort(arr,m+1,r,p);
Merge_Array(arr,l,m,r,p);
}
}
public static void Merge_sort(int[] arr,int n){
for(int i=0;i<=n;i++)
p[i]=0;
merge_sort(arr,0,n-1,p);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr=new int[4000];
Scanner temp=new Scanner(System.in);
int n=temp.nextInt();
for(int i=0;i<n;i++)
arr[i]=temp.nextInt();
Merge_sort(arr,n);
for(int i=0;i<n;i++)
System.out.print(arr[i]+" ");
System.out.println();
}
}