Maison  >  Article  >  Java  >  Comment optimiser davantage après avoir implémenté le tri par insertion en Java

Comment optimiser davantage après avoir implémenté le tri par insertion en Java

王林
王林avant
2020-12-29 10:12:482081parcourir

Comment optimiser davantage après avoir implémenté le tri par insertion en Java

Partage vidéo d'apprentissage : Tutoriel vidéo Java

Insertion normale : opérer à partir du deuxième élément du tableau, lorsqu'il est trouvé Lorsque l'élément précédent est plus grand que lui, une opération d'échange est effectuée.

static int[] insertSort(int[] array){
        int len = array.length;
        for (int begin = 1; begin < len; begin++){
            int cur = begin;
            while (cur > 0 && array[cur] < array[cur-1]){
                int tmp = array[cur];
                array[cur] = array[cur-1];
                array[cur-1] = tmp;
                cur--;
            }
        }
        return array;
    }

La première étape de l'optimisation : opérer à partir du deuxième élément du tableau S'il s'avère que l'élément précédent est plus grand que lui, reculez l'élément précédent jusqu'à ce que le pointé soit atteint. L'élément est supérieur ou égal à son élément précédent. À ce stade, la position pointée par cur est la position où l'élément à insérer doit être inséré.

    static int[] insertSort2(int[] array){
        int len = array.length;
        for (int begin = 1; begin < len; begin++){
            int cur = begin;
            int tmp = array[cur];
            while (cur > 0 && array[cur] < array[cur-1]){
                array[cur] = array[cur-1];
                cur--;
            }
            array[cur] = tmp;
        }
        return array;
    }

Optimisation de la deuxième étape

Le troisième algorithme est essentiellement le même que le deuxième. Ils trouvent tous le. position pour insérer et déplacer les éléments, mais le troisième algorithme réduit le nombre de comparaisons par recherche binaire, c'est-à-dire les appels à la fonction cmp, et réduit également les appels à la fonction swap. Il est plus rapide de trouver la position où l'élément actuel doit être inséré, puis de le déplacer, ce qui améliore l'efficacité.

static int[] insertSort3(int[] array){
        int len = array.length;

        for (int begin = 1; begin < len; begin++){
            int v = array[begin];
            int insertIndex = search(array,begin);
            // 将 [insertIndex, begin) 范围内的元素往右边挪动一个单位
            for (int i = begin; i > insertIndex; i--){
                array[i] = array[i-1];
            }
            array[insertIndex] = v;
        }
        return array;
    }
    static int search(int[] array, int index){
        int begin = 0;
        int end = index;
        while(begin < end){
            int mid = (begin+end) >> 1;
            if (array[index] < array[mid]){
                end = mid;
            }else{
                begin = mid+1;
            }
        }
        return begin;
    }

Il convient de noter qu'après avoir utilisé la recherche binaire, seul le nombre de comparaisons est réduit, mais la complexité temporelle moyenne du tri par insertion est toujours O(n^2)

L'effet de la séparation de l'opération de déplacement :

    package com.mj.sort.cmp;import com.mj.sort.Sort;public class InsertionSort3<T extends Comparable<T>> extends Sort<T> {

	//	protected void sort() {//		for (int begin = 1; begin < array.length; begin++) {//			T v = array[begin];//			int insertIndex = search(begin);//			// 将 [insertIndex, begin) 范围内的元素往右边挪动一个单位			for (int i = begin - 1; i >= insertIndex; i--) {							}//			for (int i = begin; i > insertIndex; i--) {//				array[i] = array[i - 1];//			}//			array[insertIndex] = v;//		}//	}
	
	@Override
	protected void sort() {
		for (int begin = 1; begin < array.length; begin++) {
			insert(begin, search(begin));	//元素索引给你,你告诉这个位置的元素往哪插
		} 
	}
	
	/**
	 * 将source位置的元素插入到dest位置
	 * @param source
	 * @param dest
	 */
	private void insert(int source, int dest) {
		T v = array[source];
		for (int i = source; i > dest; i--) {
			array[i] = array[i - 1];
		}
		array[dest] = v;
	}
	
	/**
	 * 利用二分搜索找到 index 位置元素的待插入位置
	 * 已经排好序数组的区间范围是 [0, index)
	 * @param index
	 * @return
	 */
	private int search(int index) {
		int begin = 0;
		int end = index;
		while (begin < end) {
			int mid = (begin + end) >> 1;
			if (cmp(array[index], array[mid]) < 0) {
				end = mid;
			} else {
				begin = mid + 1;
			}
		}
		return begin;
	}}

Recommandations associées : Tutoriel d'introduction à Java

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer