归并排序算法

mac2022-06-30  55

通过将数组分为两组及以上,在分组进行排序,最后将排序好的分组进行整合,通过比较两数组的最大和最小值来进行比较,即数组1的最大元素和数组2最小元素进行比较,若不成立,则反过来进行对比,然后便逐一排序分组,(ps:自己理解)

归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取。

工作原理:

1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2、设定两个指针,最初位置分别为两个已经排序序列的起始位置

3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4、重复步骤3直到某一指针达到序列尾

5、将另一序列剩下的所有元素直接复制到合并序列尾。

代码如下:

package com.qdcz.breadth.demo;

/** * * <p>Title: MergeA</p> * <p>Description:归并排序算法实现类 </p> * <p>Company: 奇点创智</p> * <p>Version: 1.0</p> * @author Administrator * @date 2017年6月6日 下午4:52:30 */public class MergeA { public static void main(String[] args) { int[] data ={23,3,5,4,2,54,24,55}; print(data); mergeSort(data); System.out.println("排序后的数组:"); print(data); } /** * *<p>Title: mergeSort</p> *<p>Description:给定 数组左右索引</p> *@param data *@return void *@author Administrator *@date 2017年6月6日 下午5:10:01 */ public static void mergeSort(int [] data){ sort(data,0,data.length-1); } /** * *<p>Title:print </p> *<p>Description:,对整数组分开并进行递归 </p> *@param data *@param left *@param right *@return void *@author Administrator *@date 2017年6月6日 下午5:07:43 */ private static void sort(int[] data, int left, int right) { if(left>=right) return; int center=(left+right)/2; sort(data,left,center); sort(data,center+1,right); merge(data,left,center,right); print(data); }

/** * *<p>Title: print</p> *<p>Description: 对数组进行输出</p> *@param data *@return void *@author Administrator *@date 2017年6月6日 下午5:07:14 */ private static void print(int[] data) { for (int i = 0; i < data.length; i++) { System.out.print(data[i]+"\t"); } System.out.println(); }

/** * *<p>Title: merge</p> *<p>Description: 归并排序算法核心方法,将两个分开数组合并</p> *@param data *@param left 左数组第一个 *@param center 全数组中心索引 *@param right 右数组最后一个元素索引 *@return void *@author Administrator *@date 2017年6月6日 下午5:04:18 */ private static void merge(int[] data, int left, int center, int right) { int[] temp=new int[data.length];//建立新的数组 int mid=center+1;// 右数组第一个元素索引 int thrid=left;// third 记录临时数组的索引 int tmp=left;// 缓存左数组第一个元素的索引 while(left<=center&&mid<=right){ // 从两个数组中取出最小的放入临时数组 if(data[left]<=data[mid]){ temp[thrid++]=data[left++]; }else{ temp[thrid++]=data[mid++]; } } // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个) while(mid<=right){ temp[thrid++]=data[mid++]; } while(left<=center){ temp[thrid++]=data[left++]; } //将临时数组中的内容拷贝回原数组中 // (原left-right范围的内容被复制回原数组) while(tmp<=right){ data[tmp]=temp[tmp++]; } }}

转载于:https://www.cnblogs.com/1x-zfd50/p/6959007.html

相关资源:C语言二路归并排序算法
最新回复(0)