常见排序方法之归并排序

归并排序算法详解与实现

简介

归并排序是一种常见的排序方法,其核心思想是分而治之,利用两个有序的数组,依次选取出数组中最小的数,构建成新的数组,再进行迭代,最终实现对整个数组的排序。

实现

首先需要有一个函数对数组进行划分,完成递归的过程

// arr为需要排序的数组,L为开始排序的元素下标,R为结束排序的元素下标
public static void process(int[] arr, int L, int R) {
	if (L = R) {
		return;
	}
	int mid = L + ((R - L) >> 1);	// 此处是计算中间值mid
	process(arr, L, mid);			// 此处进入递归,将原数组划分为左右两部分,直至L = R时跳出递归
	process(arr, mid + 1, R);
	merge(arr, L, mid, R);			// 当跳出递归之后,进入归并排序的函数
}

将归并过程封装成一个函数,递归后产生的数组依次调用该函数

// arr为需要进行归并的数组,L为开始排序的元素下标,M为该数组的中间下标,R为结束排序的元素下标
public static void merge(int[] arr, int L, int M, int R) {
	int helpArr = new int[R - L + 1];	// 建立一个辅助数组,临时存放排序好的元素,数组的大小为需要排序的范围的大小
	int p1 = L;		// p1指向左数组的最左侧
	int p2 = M + 1;	// p2指向右数组的最左侧
	int i = 0		// i指向helpArr数组的当前元素
	while (p1 <= M && p2 <= R) {	// p1,p2指针都在各自数组范围内
		helpArr[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2] ++;		
			// 判断左右两个数组的大小,取小的放到helpArr[i]处,同时i自增,赋值给helpArr[i]的数组左数组或者右数组自增 ,另一个保持不变
	}
	// 完成了上一个循环,必然有一个指针越界,将指针没越界的那个数组直接赋值进入新数组即可,因为递归时必然将每个子数组都排好了序
	while (p1 <= M) {
		helpArr[i++] = arr[p1++];
	}
	while (p2 <= R) {
		helpArr[i++] = arr[p2++];
	}
	// 覆盖原数组
	for (i = 0; i < helpArr.length; i ++) {
		arr[i] = helpArr[i];
	}
}

完整代码

import java.util.Arrays;

public class MergeSort {
    public static void process(int[] arr, int L, int R) {
        if (L == R) {
            return;
        }
        int mid = L + ((R - L) >> 1);
        process(arr, L, mid);
        process(arr, mid + 1, R);
        merge(arr, L, mid, R);
    }

    public static void merge(int[] arr, int L, int M, int R) {
        int[] helpArr = new int[R - L + 1];
        int p1 = L;
        int p2 = M + 1;
        int i = 0;
        while (p1 <= M && p2 <= R) {
            helpArr[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
        }
        while (p1 <= M) {
            helpArr[i++] = arr[p1++];
        }
        while (p2 <= R) {
            helpArr[i++] = arr[p2++];
        }
        for (i = 0; i < helpArr.length; i ++) {
            arr[L + i] = helpArr[i];
        }
    }

    public static void main(String[] args) {
        int[] arr = {5, 6, 7, 1, 2, 3};
        process(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值