您的位置:首页 > 编程语言 > C语言/C++

归并排序

2015-06-05 16:55 330 查看

排序算法之归并排序

归并排序算法是用分治策略实现对n个元素进行排序的算法。

其基本思想是:将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合。

1、Java代码实现

import java.util.Random;
public class MergeSort {
//覆盖mergeSort方法,p的值为0,r的值为数组长度减1
public static void mergeSort(int[] a){
int len = a.length - 1;
mergeSort(a,0,len);
}
//递归实现归并排序
public static void mergeSort(int[] a,int p, int r)
{
if(p < r){
int q = (p+r)/2;
mergeSort(a,p,q);
mergeSort(a,q+1,r);
merge(a,p,q,r);

}
}

public static void merge(int[] a, int p, int q, int r)
{
final int MAX = 10000;
//MAX是哨兵的值,设为大于排序数组任何值的数值
int n1 = q-p+1;
int n2 = r-q;
//加1是因为要加入哨兵,从而不需要判断数组是否已空
int[] R = new int[n2+1];
for(int i=0; i < n1; i++)
{
L[i] = a[p+i];
}
for(int j=0; j<n2; j++){
R[j] = a[q+j+1];
}
L[n1] = MAX;
R[n2] = MAX;

int i =0,j =0;
for(int k =p; k <r+1; k++){
if(L[i] <= R[j]){
a[k] = L[i];
i++;
}
else{
a[k] = R[j];
j++;
}
}
}

public static void main(String[] args){
Random rand = new Random(47);
int num = 20;
int[] a = new int[num];
System.out.println("排序前");
for(int i = 0; i < num; i++){
a[i] = rand.nextInt(100);
System.out.print(a[i] + " ");
}
System.out.println();
mergeSort(a);
System.out.println("排序后:");
for(int j : a)
System.out.print(j + " ");
}
}


2、 c++代码实现

2.1 递归实现,与java实现的思路一致。

#include<iostream>
using namespace std;

#define MAXMUM  10000;
template<class Type>
void MergeSort(Type a[], int left, int right){
if (left < right){
int mid = (left + right) / 2;
MergeSort(a, left, mid);
MergeSort(a, mid + 1, right);
Merge(a, left, mid, right);
}
}

template<class Type>
void Merge(Type a[], int left, int mid, int right){
int n1 = mid - left + 1;
int n2 = right - mid;
int *L = new int[n1 + 1];
int *R = new int[n2 + 1];
int i, j, k;

for (i = 0; i < n1; i++){
L[i] = a[left + i];
}

for (j = 0; j < n2; j++){
R[j] = a[mid + j + 1];
}

L[n1] = MAXMUM;
R[n2] = MAXMUM;

for (i = 0, j = 0, k = left; k <= right; k++){
if (L[i] <= R[j]){
a[k] = L[i];
i++;
}
else{
a[k] = R[j];
j++;
}
}

delete[] L;
delete[] R;
}

int main(){
cout << "Before Sort:";
int num = 100;
int *arr= new int[num];
for (int i = 0; i < num; i++){
arr[i] = rand()%100;
cout << arr[i] << " " ;
}
cout << endl;
MergeSort(arr, 0, num - 1);
cout << "After Sort:";
for (int i = 0; i < num; i++){
cout << arr[i] << " " ;
}
cout << endl;
system("pause");
return 0;
}


2.2 非递归实现

从分治策略入手,可以消除算法中的递归。算法MergeSort的递归过程只是将待排序集合一分为二,直至待排序集合只剩下一个元素为止,然后不断合并两个排好序的数组段。按此机制,可以首先将数组a中相邻元素两两配对。用合并算法将它们 排序,构成n/2 的排好序的子数组段,然后再将它们排序成长度为4的排好序的子数组段,如此继续下去,直至整个数组排好序。

#include<iostream>
using namespace std;

//消去递归的合并排序算法
template<class Type>
void MergeSort(Type a[], int n){
Type *b = new Type
;
int s = 1;
while (s < n){
MergePass(a, b, s, n);//合并到数组b
s += s;
MergePass(b, a, s, n);//合并到数组a
s += s;
}
}

//用于合并排好序的相邻数组段
template<class Type>
void MergePass(Type x[], Type y[], int s, int n){
//合并大小为s的相邻子数组
int i = 0;
while (i <= n - 2 * s){
//合并大小为s的相邻2段子数组
Merge(x, y, i, i + s - 1, i + 2 * s - 1);
i = i + 2 * s;

}
//剩下的元素个数少于2s
if (i + s < n) Merge(x, y, i, i + s - 1, n - 1);
else for (int j = i; j <= n - 1; j++)y[j] = x[j];
}

template<class Type>
void Merge(Type c[], Type d[], int l, int m, int r){
//合并c[l:m]和c[m+1,r]到d[l+r]
int i = l;
int j = m + 1;
int k = l;
while ((i <= m) && (j<=r))
if (c[i] <= c[j]) d[k++] = c[i++];
else d[k++] = c[j++];
if (i > m) for (int q = j; q <= r; q++) d[k++] = c[q];
else for (int q = i; q <= m; q++) d[k++] = c[q];
}

int main(){
cout << "Before Sort:";
const int num = 100;
int  arr[num];
for (int i = 0; i < num; i++){
arr[i] = rand() % 100;
cout << arr[i] << " ";
}
cout << endl;
MergeSort(arr, num);
cout << "After Sort:";
for (int i = 0; i < num; i++){
cout << arr[i] << " ";
}
cout << endl;
delete[] arr;
system("pause");
return 0;
}


3、 python语言的递归实现

#coding:utf-8
import random
def merge_sort(array):
length = len(array)
if length <= 1:return array
m = length/2
left = array[:m]
right = array[m:]
left = merge_sort(left)
right = merge_sort(right)
return merge(left, right)

def merge(left, right):
result = []
while len(left)>0 and len(right)>0:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
result.extend(left)
result.extend(right)
return result
if __name__ == '__main__':
num = 100
arr = []
for i in range(num):
arr.append(random.randint(0,100))
print "BeforeSort: ",arr
print "AfterSort: ",merge_sort(arr)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息