归并排序算法的原理及JAVA实现
归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为:
1)划分子表
2)合并半子表
首先我们来讨论归并算法,归并算法将一系列数据放到一个向量中,索引范围为[first,last],这个序列由两个排好序的子表构成,以索引终点(mid)为分界线,以下面一个序列为例
7,10,19,25,12,17,21,30,48
这样的一个序列中,分为两个子序列 7,10,19,25 和 12,17,21,30,48,如下图所示:
再使用归并算法的时候的步骤如下:
第一步:比较v[indexA]=7和v[indexB]=12,将较小的v[indexA]取出来放到临时向量tempArray中,然后indexA加1
第二步:比较v[indexA]=10和v[indexB]=12,将较小的10放到临时变量tempArray中,然后indexA++;
第三步:比较v[indexA]=19与v[indexB]=12,将较小的12存放到临时变量tempArray中,然后indexB++;
第四步到第七步:按照以上规则,进行比对和存储,得到如下结果:
最后一步:将子表b中剩余项添加到临时向量tempArray中
然后将临时变量中的值按照索引位置,拷贝回向量v中,就完成了对向量v 的归并排序
Java实现代码:
package com.sort.merge;
public class Merge {
/**
* 分治法,自顶向下,递归分割数组,最终归并
*/
public static void merge(int[] arr,int start,int end){
if(start int mid = (start+end)/2; merge(arr,start,mid);//递归地对arr[start...mid]排序 merge(arr,mid+1,end);//递归地对arr[mid+1...end]排序 doMerge(arr,start,mid,end);//组合,将两个有序区合并为一个有序区} } //组合,归并 public static void doMerge(int[] arr,int start,int mid,int end){ int tempIndex = start; int Index = start; int right = mid + 1; int temp[] = new int[arr.length]; //两个子序列比较,小的放入临时数组 while(start <= mid && right <= end){ if(arr[start] <= arr[right]){ temp[tempIndex++] = arr[start++]; }else{ temp[tempIndex++] = arr[right++]; } } //剩下的右边的元素加入临时数组 while(start <= mid){ temp[tempIndex++] = arr[start++]; } //剩下的右边的元素加入临时数组 while(right <= end){ temp[tempIndex++] = arr[right++]; } //复制临时数据temp[]中的数据到arr[]数组 while(Index < end){ arr[Index] = temp[Index++]; } } public static void main(String[] args) { // TODO Auto-generated method stub int arr[] = {2,4,6,8,1,3,5,9}; merge(arr,0,arr.length-1); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); } } } 采用分治法进行自顶向下的算法设计,形式更为简洁。 (1)分治法的三个步骤 设归并排序的当前区间是R[low..high],分治法的三个步骤是: ①分解:将当前区间一分为二,即求分裂点 ②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序; ③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。 递归的终结条件:子区间长度为1(一个记录自然有序)。 (2)具体算法 void MergeSortDC(SeqList R,int low,int high) {//用分治法对R[low..high]进行二路归并排序 int mid; if(low mid=(low+high)/2; //分解 MergeSortDC(R,low,mid); //递归地对R[low..mid]排序 MergeSortDC(R,mid+1,high); //递归地对R[mid+1..high]排序 Merge(R,low,mid,high); //组合,将两个有序区归并为一个有序区} }//MergeSortDC #include count++; }//满足条件,前移 if(count==0) break;//位置恰当,退出 } } }//insort插入排序函数 selsort(int a[30001]) { int i,j,temp; for(i=1;i<30000;i++) for(j=i+1;j<30001;j++) if(a[i]>a[j]) { temp=a[j]; a[j]=a[i]; a[i]=temp; } }//选择排序 bubsort(int a[30001]) { int i,j,temp; for(i=1;i<30001;i++) for(j=30000;j>i;j--) { if(a[j-1]>a[j]) { temp=a[j-1]; a[j-1]=a[j]; a[j]=temp; } } }//冒泡排序 int partition(int a[30001],int low,int high) import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; public class GuiBing { public static void main(String[] args) throws Exception { int datalength=1000000; GuiBing gui=new GuiBing(); int[] array1=gui.createArray(datalength); int[] array2=gui.createArray(datalength); Thread.sleep(20000); long startTime = System.nanoTime();//纳秒精度 long begin_freeMemory=Runtime.getRuntime().freeMemory(); int[] final_array=gui.guibing(array1,array2); boolean result=gui.testResult(final_array); long end_freeMemory=Runtime.getRuntime().freeMemory(); System.out.println("result===="+result); long estimatedTime = System.nanoTime() - startTime; System.out.println("elapsed time(纳秒精 度):"+estimatedTime/100000000.0); System.out.println("allocated memory:"+(begin_freeMemory-end_freeMemory)/1000.0+" KB"); Thread.sleep(20000); } /** * 显示数组的内容 * @param array */ private static void dispalyData(int[] array) { for(int i=0;i java程序员必学的十种程序算法 算法1:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。 算法步骤: 1 从数列中挑出一个元素,称为“基准”(pivot), 2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。 3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 算法2:堆排序算法 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 堆排序的平均时间复杂度为Ο(nlogn) 。 算法步骤: 创建一个堆H[0..n-1] 把堆首(最大值)和堆尾互换 3. 把堆的尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置 4. 重复步骤2,直到堆的尺寸为1 算法3:归并排序 归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 算法步骤: 归并排序算法实现(迭代和递归)\递归实现归并排序的原理如下: 递归分割: 递归到达底部后排序返回: 最终实现排序: #include } while(i 冒泡排序法 1.public class SortArray_01 { 2. public static void main(String args[]) { 3. int[] array = { 14, 5, 86, 4, 12, 3, 21, 13, 11, 2, 55 }; // 创建一个初始化的一维数组array 4. System.out.println("未排序的数组:"); 5. for (int i = 0; i < array.length; i++) { // 遍历array数组中的元素 6. System.out.print(" " + array[i]); // 输出数组元素 7. if ((i + 1) % 5 == 0) // 每5个元素一行 8. System.out.println(); 9. } 10. int mid; // 定义一个中间变量, 起到临时存储数据的作用 11. for (int i = 0; i < array.length; i++) { // 执行冒 泡排序法 12. for (int j = i; j < array.length; j++) { 13. if (array[j] < array[i]) { 14. mid = array[i]; 15. array[i] = array[j]; 16. array[j] = mid; 17. } 18. } 19. } 20. System.out.println("\n使用冒泡法排序后的数组:"); 21. for (int i = 0; i < array.length; i++) { // 遍历排好序的array数组中的元素 22. System.out.print(" " + array[i]); // 输出数组元素 23. if ((i + 1) % 5 == 0) 24. System.out.println(); // 每5 个元素一行 25. } 26. } 27.} 数组递增排序 JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法、冒泡法、选择排序法、插入排序法。 快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现。 冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。 选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。 插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序。下面我就将他们的实现方法一一详解供大家参考。 <1>利用Arrays带有的排序方法快速排序 import java.util.Arrays; publicclass Test2{ publicstaticvoid main(String[] args){ int[] a={5,4,2,4,9,1}; Arrays.sort(a); //进行排序 for(int i: a){ System.out.print(i); } } } <2>冒泡排序算法 publicstaticint[] bubbleSort(int[] args){//冒泡排序算法 for(int i=0;i 实验名称归并排序分治策略的设计与实现实验方案实验成绩实验日期实验室信息系统设计与仿真室I 实验操作 实验台号班级姓名实验结果 一、实验目的 1、熟悉分治法求解问题的抽象控制策略; 2、熟悉在顺序存储表示下求解分类问题的递归算法设计; 3、通过实例转换, 掌握分治法应用。 二、实验任务 ①从文件中读取数据信息; ②利用归并排序算法,进行排序; ③输出排序结果。 三、实验设计方案 1、结构体设计 用数组存放排序数据。 2、自定义函数设计 ①函数原型声明 int input(int A[]); //从文件读入待排序的数据 void merge(int A[],int low,int mid,int high); // 两个相邻有序数组的归并 void mergesort(int A[],int low,int high); // 归并排序 void input(int A[], int n); // 输出排序结果 ②两个相邻的有序子数组的合并 思路:从两个已排好序的子数组的首元素开始,依次比较大小,按从小到大的顺序存放在b[]数组中,然后转存到A[]数组中。 void merge(int A[],int low,int mid,int high) { int b[N]; int i,j,k = 0; int l = low; //已排序部分1的起始下标 int h = mid+1; //已排序部分2的起始下标 while(l <= mid && h <= high) //两个有序部分合并到b数组中 if(A[l] < A[h]) b[k++] = A[l++]; else Java程序员必知的8大排序本文主要详解了Java语言的8大排序的基本思想以及实例解读,详细请看下文8种排序之间的关系: 1,直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的。如此反复循环,直到全部排好顺序。 (2)实例C (++)内部排序汇总(快速排序&冒泡排序&堆排序&选择排序&插入排序&归并排序)
简单的归并排序算法例子
java程序员必知的十种程序算法
归并排序算法实现 (迭代和递归)
JAVA数组的排序方法实例
JAVA中运用数组的四种排序方法
归并排序分治策略的设计与实现
java中8大排序方法