Mesclando recursiva algoritmo e não recursivo

Um não-recursiva

Qual é o merge sort?

  • merge sort (MERGE-SORT) é baseado em uma operação eficiente de merge algoritmo de classificação, que é muito típica aplicação utiliza um dividir e conquistar (Divide and Conquer) a. A sequência combinada foi ordenada, sequência totalmente ordenada, isto é, cada primeira sequência ordenada, e, em seguida, ordem para fazer sequências entre segmentos. Se duas se fundiram em uma lista lista ordenada ordenou, chamado de maneira direta. Método de classificação de intercalação de uma espécie estável.
/**
     * 非递归代码实现
     */
    private static <T extends Comparable> void mergeSort(T[] arr){
        for (int i = 1;i<arr.length;i*=2){
            merge(arr,i);
        }
    }
    private static<T extends Comparable> void merge(T[] arr, int gap) {
        int left1 = 0;
        int right1 = left1+gap-1;
        int left2 = right1+1;
        int right2 = left2+gap-1>arr.length-1?arr.length-1:left2+gap-1;//防止right越界
        T []brr =(T[]) new Comparable[arr.length];//brr实质就是一个中间数组,存储每次并归后的值,然后再传给arr
        //为下次归并做准备
        int j = 0;//控制brr数组下标
        //前提有两个归并段
        while (left2<arr.length){//保证了第二个归并段的存在
            while (left1<=right1 && left2<=right2){//防止越界
                if (arr[left1].compareTo(arr[left2])<0){//谁小谁进新数组
                    brr[j++] = arr[left1++];
                }else {
                    brr[j++] = arr[left2++];
                }
            }
            if (left2>right2){//说明left2已经走完了,没元素了,那就让left1到right1剩下元素直接入brr就可以了
                while (left1<=right1){
                    brr[j++] = arr[left1++];
                }
            }
            if (left1>right1){//同理
                while (left2<=right2){
                    brr[j++] = arr[left2++];
                }
            }
            //更新指针
            left1 = right2+1;
            right1 = left1+gap-1;
            left2 = right1+1;
            right2 = left2+gap-1>arr.length-1?arr.length-1:left2+gap-1;
        }
        //只剩一个归并段
        while (left1<=arr.length-1){
            brr[j++] = arr[left1++];
        }
        System.arraycopy(brr,0,arr,0,arr.length);
    }

Em segundo lugar, recursivo

Aqui Insert Picture Descrição

  • Estamos focados olhada na implementação de código recursiva: Na verdade, nada sub-etapa especial, uma é para sair de elementos da matriz, mas estamos utilizado para completar o sequenciamento do processo recursivo, o que é muito importante, como recursão? Como usar?

Código pontos processo de aplicação:

  • por exemplo: int [] arr = { 2,5,6,7,8,9,5}, índices de 0 a 6, pode-se definir o início eo fim coordenadas de dois elementos arr, e, em seguida, definir uma intermédios coordenadas elemento, de modo análogo ao dicotomia método para dividir o elemento de
    códigos:
 public static<T extends Comparable> void mergeSort2(T []arr,int left,int right,T[]brr){
        if (left<right){
            int mid = left+(right-left)/2;//中间索引
            mergeSort2(arr,left,mid,brr);//左递归
            mergeSort2(arr,mid+1,right,brr);//右递归
            //合并
            merge2(arr,left,mid,right,brr);
        }
    }

O código combinado para atingir:

 //分合
    public static<T extends Comparable> void mergeSort2(T []arr,int left,int right,T[]brr){
        if (left<right){
            int mid = left+(right-left)/2;//中间索引
            mergeSort2(arr,left,mid,brr);//左递归
            mergeSort2(arr,mid+1,right,brr);//右递归
            //合并
            merge2(arr,left,mid,right,brr);
        }
    }
    /**
     * @param arr 原始数组
     * @param left 左边有序序列的初始索引
     * @param mid 中间索引
     * @param right 右边索引
     * @param brr 中转索引
     * @param <T>
     */
    public static<T extends Comparable<T>> void merge2(T[]arr,int left,int mid,int right,T[]brr){
        int i = left;//初始化 i ,左边序列初始索引
        int j = mid +1;//右边序列初始索引
        int t = 0;//控制brr数组下标
        while (i<= mid && j<=right){
            if (arr[i].compareTo(arr[j])<0){//小的入栈
                brr[t++] = arr[i++];
            }else {
                brr[t++] = arr[j++];
            }
        }
        //把剩余元素直接加到brr中
        while (i<=mid){//左边序列有剩余
            brr[t++] = arr[i++];
        }
        while (j<=right){//右边元素有剩余
            brr[t++] = arr[j++];
        }
        //把brr数组拷贝到arr
        t = 0;
        int brrLeft = left;//
        while (brrLeft<=right){
            arr[brrLeft++] = brr[t++];//0-1,2-3,0-3
        }
    }
Publicado 22 artigos originais · ganhou elogios 2 · Visualizações 358

Acho que você gosta

Origin blog.csdn.net/qq_44682003/article/details/104794000
Recomendado
Clasificación