Orden de fusión de notas de algoritmo

Combinar ordenación

Introducción

Merge sort (MERGE SORT) es un método que utiliza el tipo de pensamiento de fusión para realizar, el algoritmo utiliza la estrategia clásica de dividir y conquistar (dividir y conquistar) (dividir y conquistar los puntos del problema (dividir) en problemas más pequeños y luego recursivos solución, en la etapa de conquista , las respuestas obtenidas en las etapas divididas se "fijan" juntas, es decir, divide y vencerás).

Es decir, la idea central del algoritmo es la idea de dividir y conquistar.

Ilustración dinámica

Escriba la descripción de la imagen aquí

Escriba la descripción de la imagen aquíDescubrimos que nuestros puntos no realizaban otras funciones, solo dividimos nuestra matriz

Proporcionar condiciones para nuestro siguiente tratamiento.

Echemos un vistazo a su complejidad nuevamente, tenemos 8 datos, pero un total de 7 fusiones

Entonces, su complejidad es el crecimiento lineal, a diferencia de otros algoritmos que requieren ritmos, que es un crecimiento cuadrático.

Veamos qué se hizo en la última fusión.

Escriba la descripción de la imagen aquí

Escriba la descripción de la imagen aquí

En otras palabras, nuestra clasificación de combinación requiere una matriz auxiliar , que también es la parte más complicada de nuestro 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;
		}
	}
}

A lo que debemos prestar atención es a que usamos la recursividad al copiar la matriz, lo que significa que fusionamos dos dos al principio, por lo que la matriz auxiliar no copia directamente 8 datos al principio, es decir, nuestra fusión tempLeft y right No 0 y 7, sino 0 1 2 3 y luego se fusionaron en 0 3, que son los primeros cuatro datos, definitivamente habrá 4 7 fusiones más tarde, y finalmente nuestra matriz completa de 0 7

Supongo que te gusta

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