首页 > 编程语言 >常见排序算法之归并排序

常见排序算法之归并排序

时间:2023-01-18 23:33:26浏览次数:43  
标签:归并 temp int arr ++ 算法 数组 排序 left


文章目录

  • ​​1、概述​​
  • ​​2、测试代码​​
  • ​​3、小案例​​



1、概述

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

归并排序可以分为两部分,一部分用来分解数组(使用递归的方式),一部分用来合并数组

常见排序算法之归并排序_数组

常见排序算法之归并排序_递归_02



2、测试代码

核心思想:将这个算法分为分(分解)和治(合并)两部分。将我们最初的数组就不断地递归分解:一分二,二分四,四分八…直到我们数组中的元素变成一个一个的。然后在分(分解)完成的时候,再进行一个治(合并),…八个合并为四个,四个合并为两个,两个合并为一个,每次合并完成时,对应的新数组都是按照顺序排列好的,直到合并为一个已经排好序的数组位置。

public class MergetSortTest01 {
public static void main(String[] args) {
int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
int[] temp = new int[arr.length];
//调用我们的分解、合并的方法
mergeSort(arr, 0, arr.length - 1, temp);
System.out.println(Arrays.toString(arr));
}

//一:分解+合并的方法
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
//先向左递归进行分解
mergeSort(arr, left, mid, temp);

//左递归分解完毕后,开始向右递归进行分解
mergeSort(arr, mid + 1, right, temp);

//当该递归方法执行完一次以后,就开始执行该方法,用于合并分解后的数组
merge(arr, left, mid, right, temp);
}
}


//二:合并的方法
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
int t = 0;

//这里有两个不同数组:第一个为被合并的数组(不同的位置上的数据),第二个为合并后的新数组
//1.将我们两个数组的数字进行比较,并且按照一定的顺序放入到我们的新的数组里面
while (i <= mid && j <= right) {
//2.将我们被合并的数组的i位置上的值和j位置上的值进行比较,谁小就放谁
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else {
temp[t] = arr[j];
t++;
j++;
}
}

//3.上面的方式的补充部分
//左边的有序序列还有剩余的数字,填充到temp数组中
while (i <= mid) {
//不断的将元数组的index和临时数组的index后移,用于填充数值
temp[t] = arr[i];
t++;
i++;
}
//4.右边的有序序列还有剩余的数字,填充到temp数组中
while (j <= right) {
//不断的将元数组的index和临时数组的index后移,用于填充数值
temp[t] = arr[j];
t++;
j++;
}

//5.将(left~right的)temp数组的元素拷贝到arr中
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
}
}



3、小案例

利用我们以有的条件,进行一个小案例的测试:计算将数组长度为80000的乱序数组排序所花费的时间

public class MergetSortTest02 {
public static void main(String[] args) {



int[] arr = new int[80000];

for (int i = 0; i < 80000; i++) {
arr[i] = (int) (Math.random()*80000);
}

long start = System.currentTimeMillis();

int[] temp = new int[arr.length];
mergeSort(arr, 0, arr.length - 1, temp);
long end= System.currentTimeMillis();
System.out.println("归并排序的时间为:"+(end-start));
}


//一:分解+合并的方法
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
//先向左递归进行分解
mergeSort(arr, left, mid, temp);

//左递归分解完毕后,开始向右递归进行分解
mergeSort(arr, mid + 1, right, temp);

//合并
merge(arr, left, mid, right, temp);
}
}


//二:合并的方法
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
int t = 0;

while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else {
temp[t] = arr[j];
t++;
j++;
}
}

//补充没有赋值到的数据
while (i <= mid) {
temp[t] = arr[i];
t++;
i++;
}
while (j <= right) {
temp[t] = arr[j];
t++;
j++;
}

//完成数组值的交换
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
}
}

我们的归并排序,递归的次数是指数形式增加的。所以该排序方式,更适合于数据较多的时候使用


标签:归并,temp,int,arr,++,算法,数组,排序,left
From: https://blog.51cto.com/u_15942107/6019570

相关文章

  • 常见排序算法之希尔排序
    文章目录​​1、概述​​​​2、希尔排序之交换法​​​​3、希尔排序之移动法​​​​4、测试案例​​1、概述由于简单的插入排序每次数据量变多的时候,数据需要移动且交换......
  • m基于遗传优化算法的公式参数拟合matlab仿真
    1.算法描述遗传算法的原理        遗传算法GA把问题的解表示成“染色体”,在算法中也即是以二进制编码的串。并且,在执行遗传算法之前,给出一群“染色体”,也即是假......
  • 常见排序算法之选择排序
    文章目录​​1、概述​​​​2、代码实现​​​​3、测试代码​​1、概述选择排序(Selectionsort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出......
  • 常见排序算法之冒泡排序
    文章目录​​1、概述​​​​2、传统代码​​​​3、优化后代码​​​​4、测试案例​​1、概述冒泡排序(BubbleSort),是一种的较简单且常见的的排序算法。它重复地访问排序的......
  • 常见排序算法之插入排序
    文章目录​​1、概述​​​​2、代码实现​​​​3、测试代码​​1、概述插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简......
  • 17种编程语言实现排序算法-冒泡排序
    开源地址https://gitee.com/lblbc/simple-works/tree/master/sort/bubbleSort1.安卓Java版privatevoidsort(int[]array){for(inti=0;i<array.length......
  • 司守奎《数学建模算法与应用》课后习题:线性规划
    写在最前面:    我是一个刚学数模的小白,觉得把自己的思路和代码啊公式写出来能提升学习效率,在参考了司守奎老师的《数学建模算法与应用》(第二版)一书后想把自己的想......
  • java-数组相关的算法(尚硅谷)
    1.数组元素的赋值(杨辉三角、回形数等)2.求数值型数组中元素的最大值、最小值、平均数、总和等3.数组的复制、反转、查找(线性查找、二分法查找)4.数组元素的排序算法一......
  • J Tokitsukaze and Sum of MxAb【2023牛客寒假算法基础集训营2】
    J TokitsukazeandSumofMxAb原题链接题意给出长为n的序列,对于所有的i,j求max\((|a_i-a_j|,|a_i+a_j|)\)之和思路对于两个负数\(a_i\)和\(a_j\),max\((|a_i-......
  • 刷算法题的一些Trick
    1字符串的输入在读字符串的时候,一般建议这么写charstr[N];//字符数组scanf("%s",str);//因为str可以当作指针,所以不用&puts(str);字符串作为函数参数的时候......