Mesclar classificação
Introdução
Merge sort (MERGE SORT) é um método que usa o tipo de pensamento merge para realizar, o algoritmo usa a estratégia clássica de dividir e conquistar (dividir e conquistar) (dividir e conquistar os pontos do problema (dividir) em problemas menores e então recursivos solução, Na etapa de conquista , as respostas obtidas nas etapas divididas são "fixadas" juntas, ou seja, dividir e conquistar).
Ou seja, a ideia central do algoritmo é a ideia de dividir para conquistar
Ilustração dinâmica
Descobrimos que nossos pontos não realizam outras funções, apenas dividem nosso array
Forneça condições para o nosso seguinte tratamento
Vamos dar uma olhada em sua complexidade novamente, temos 8 dados, mas um total de 7 mesclagens
Portanto, sua complexidade é o crescimento linear, ao contrário de outros algoritmos que exigem batimento, que é o crescimento quadrático.
Vamos ver o que foi feito na última fusão
Em outras palavras, nosso merge sort requer um array auxiliar , que também é a parte mais complicada do nosso código
Código
package 数据结构;
import java.lang.reflect.Array;
import java.util.Arrays;
//归并排序
//@author 王庆华
public class MergetSort {
public static void main(String[] args) {
//创建数组
int arr[] = {
8,4,5,7,1,3,6,2};
int temp[] = new int[arr.length];//归并排序需要一个额外的空间的
megeSort(arr, 0, arr.length-1, temp);
System.out.println("归并排序后"+Arrays.toString(arr));
}
//分解+合并方法
public static void megeSort(int[] arr,int left,int right, int[] temp){
if(left<right){
int mid = (left+right)/2;//中间索引
//向左递归进行分解
megeSort(arr, left, mid, temp);
//向右递归分解
megeSort(arr, mid+1, right, temp);
//每分解一次就合并一次
merge(arr, left, right, mid, temp);
}
}
//合并的方法
/**
*
* @param arr 需要排序的初始的数组
* @param left 左边有序子序列的初始索引
* @param right 右边有序子序列的索引
* @param mid 中间索引
* @param temp 辅助数组
*/
public static void merge(int[] arr,int left,int right,int mid,int[] temp){
int i = left;//初始化i 表示左边有序子序列的初始索引
int j = mid + 1;//j是我们右边子序列的初始索引
int t = 0; //这个是我们辅助数组的当前索引,来帮助我们在那个地方插入值
//(1)先把左右两边(有序)的数据按照规则填充到辅助数组temp中
//直到左右两边的有序序列有一边处理完毕为止
while(i <= mid && j <= right){
if(arr[i] <= arr[j]){
//左边有序子序列的当前元素<=右边有序序列的当前元素
//左边的元素填充到辅助数组
temp[t] = arr [i];
t+=1;
i+=1;
}else{
//反之就是右边进行拷贝操作
temp[t] = arr[j];
t+=1;
j+=1;
}
}
//(2)
//把有剩余数据的一边,依次填充到辅助数组中
while(i <= mid){
//说明左边有序子序列有剩余元素
temp[t] = arr[i];
t+=1;
i+=1;
}
while(j <= right){
//右边有序子序列有剩余
temp[t] = arr[j];
t+=1;
j+=1;
}
//(3)将辅助数组中的数据拷贝到arr中
//注意并不是每一次都是拷贝所有的元素
t = 0;
int tempLeft = left;//
while(tempLeft <= right){
//第一次合并时 tempLeft=0 , right = 1
//第二次 tempLeft = 2 riht = 3
//最后一次tempLeft = 0 ,right = 7
arr[tempLeft] = temp[t];
t+=1;
tempLeft+=1;
}
}
}
O que precisamos prestar atenção é que usamos recursão ao copiar o array, o que significa que mesclamos dois dois no início, então o array auxiliar não copia diretamente 8 dados no início, ou seja, nosso tempLeft e direito merge Não 0 e 7, mas 0 1 2 3 e então mesclado em 0 3, que são os quatro primeiros dados, definitivamente haverá 4 7 mesclagens mais tarde e, finalmente, nosso 0 7 inteiro array