Classificação de mesclagem de notas de algoritmo

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

Escreva a descrição da imagem aqui

Escreva a descrição da imagem aquiDescobrimos 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

Escreva a descrição da imagem aqui

Escreva a descrição da imagem aqui

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

Acho que você gosta

Origin blog.csdn.net/qq_22155255/article/details/112620258
Recomendado
Clasificación