归并排序の分而治之

归并排序可以说是分治法的一个很形象的实例

归并排序与快排不同的是,归并排序重点在整合,简单的说把相对分区有序而内部

元素乱序的两区通过归并整合成有序的序列。

归并思路(分治法):

分解:将n个元素一刀从中间分成两个序列

递归:将子序列递归的进行分区划分

解决:合并两个子序列(归并排序的重点)

归并排序的合并(以空间换时间):

申请额外的和原数组大小相同的辅助空间,将原数组元素copy到辅助空间中

定义两个指针:left right ,其中left指向辅助空间头(第一区的头),right指向辅助空间中间元素下一个(第二区的头)比较大小,每次将小的元素覆盖到原数组,并且该指针后移

(Java代码示例)

public class MergeSort {

private static int[] helper;//辅助数组

public static void main(String[] args) {

int[] a = {5,15,8,20,6};

printArray(a);

sort(a);

printArray(a);

}

static void sort(int[] a) {

helper = new int[a.length];

mergeSort(a, 0, a.length - 1);

}

/**

*

* @param arr 待排序数组

* @param p 低位

* @param r 高位

*/

static void mergeSort(int[] arr, int p, int r) {

if(p < r) {

int mid = p + ((r - p)>>1);

mergeSort(arr, p, mid);//左侧排序

mergeSort(arr, mid+1, r);//右侧排序

merge(arr, p, mid, r);

}

}


static void printArray(int[] arr){

for(int i : arr){

System.out.print(i + " ");

}

System.out.println();

}

/**

*

* @param arr 待合并数组

* @param p 低位

* @param mid 中间位置

* @param r 高位

*/

static void merge(int[] arr, int p, int mid, int r) {

//arr中的数据拷贝到helper中

System.arraycopy(arr, p, helper, p, r-p+1);

//辅助数组的两个指针

int left = p;

int right = mid + 1;

//原始数组的指针

int current = p;

while(left <= mid&&right <= r) {

if(helper[left] <= helper[right]) {

arr[current] = helper[left];

current++;

left++;

}else {

arr[current] = helper[right];

current++;

right++;

}

}

while(left <= mid) {//左边没有到头,右边不到头也可以

arr[current] = helper[left];

current++;

left++;

}

}

}

你可能感兴趣的:(归并排序の分而治之)