归并排序
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)
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 介绍一款信息管理系统的开源框架---jeecg
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- install and upgrade scrapy