JAVA Diez especie de - (rápida especie)

preludio

前奏:是一种交换式且高效的分治排序算法 简称:快速排序
快速的总体运行结构是:先排序一遍然后在进行回溯分治

Extracurricular sólo de referencia

如果与一组8000个数据的数组排序的情况下             时间差不多4毫秒不到
如果与一组80000个数据的数组排序的情况下            时间差不多50毫秒不到
如果与一组800000个数据的数组排序的情况下           时间差不多180毫秒不到
如果与一组8000000个数据的数组排序的情况下          时间差不多1.5秒不到
如果与一组80000000个数据的数组排序的情况下         时间差不多13秒不到            

prestar atención

Nota en el Nota: Si la causa está cerca de la lista ordenada de recursiva no utilice rápida tipo es propenso a desbordamiento de pila

Rápida tipo adecuado de 2 maneras

Método alterna a la izquierda y la mano derecha

pensamiento
1: 创建一个中心轴,并创建2个指针一个是左指针一个是右指针如果是以最左边元素为中心轴,就要先移动右指针在移动左指针
2:2个指针没有相撞(相撞)并停止了移动说明这时候就要对该2指针的元素相互的交换,直到指针相撞,然后将中心轴值与当前任意指针(最好以左指针)索引位置元素进行交换
3:  然后使用递归将中轴值左边区域的索引元素进行分区排列左边分区排列结束后将当前中轴值右边区域的索引元素进行分区排列
4:  什么情况下退出递归,就是当左指针>=右指针 如果没这一步会出现栈溢出
diagrama

Aquí Insertar imagen Descripción

prestar atención
如以最左/右为中心轴 移动当前的指针一定要是刚相反的指针索引 如:中心轴(最左) 就一定要先移动右指针 在移动左指针
如果以左为中心轴,又先移动左指针到时候会出现排序后的元素还是乱序的,所以一定要小心谨慎
nota gráfico

Aquí Insertar imagen Descripción
Alternativamente, el valor de índice del centro de eje del centro cuando el primer valor de índice del índice asignado al eje central, entonces el centro de eje del valor de índice asignado a un elemento

código
   //左右指针法
    public static void quickSortTheLeftAndRight(int [] arrray,int left,int right){

        //指定回溯的结束条件
        if(left>=right){
            return; //已经分组成唯一元素,无序排序及再次拆分
        }

        //指定当前中心值 已最左边的元素为中心值
        int pivot=arrray[left];

        //创建左右移动指针
        int moveLeftPoint=left;
        int moveRightPoint=right;

        while(moveLeftPoint<moveRightPoint){
            //先移动右指针
            while(moveLeftPoint<moveRightPoint&&arrray[moveRightPoint]>=pivot){
                moveRightPoint--;
            }
            //移动左指针
            while(moveLeftPoint<moveRightPoint&&arrray[moveLeftPoint]<=pivot){
                moveLeftPoint++;
            }
            if(moveLeftPoint<moveRightPoint){
                //由于相互没有碰撞所以将2个对应的指针元素进行调换位置
                int temp=arrray[moveLeftPoint];
                arrray[moveLeftPoint]=arrray[moveRightPoint];
                arrray[moveRightPoint]=temp;
            }
        }

        //指针碰撞与中心元素进行交换元素
        if(moveLeftPoint==moveRightPoint){
            arrray[left]=arrray[moveLeftPoint];
            arrray[moveLeftPoint]=pivot;
        }

        //本次排序后左边的moveLeftPoint-1的元素都比pivot小  右边的moveRightPoint+1的元素都不小于pivot
        //进行分治回溯
        quickSortTheLeftAndRight(arrray,left,moveLeftPoint-1);

        quickSortTheLeftAndRight(arrray,moveRightPoint+1,right);
    }

Datos ley de excavación

diagrama

Aquí Insertar imagen Descripción

pensamiento
  1: 以最左/右未中心轴
  2: 如果以最左为中心轴  就一开始移动右指针
     如果以最右为中心轴  就一开始移动右指针
  3: 移动指针结束并且指针没有碰撞(相对)就将当前指针元素赋值到对方指针索引位置上
  4: 当前左右指针相撞(相等) 将中心轴值赋值在当前左右指针相等的索引位置上
     所以当前中轴值以左边都是小于中轴值的元素,右边都是大于等于中轴值的元素(这就是从小到大排序)
  5: 然后使用递归将中轴值左边区域的索引元素进行分区排列
     左边分区排列结束后将当前中轴值右边区域的索引元素进行分区排列
  6: 什么情况下退出递归,就是当左指针>=右指针 如果没这一步会出现栈溢出
prestar atención
如以最左/右为中心轴 移动当前的指针一定要是刚相反的指针索引 如:中心轴(最左) 就一定要先移动右指针 在移动左指针
如果以左为中心轴,又先移动左指针到时候会出现右边的一些索引元素会被覆盖,所以一定要小心谨慎

código

//快速排序之数据挖坑法 版本3我以最左元素为中轴值
public static void quickSortPitFillDataVersion3(int []arr ,int left,int right){
    //判断2个指针是否右指定区域可以排序,> 还是=取决于  是先移动左指针还是右指针 2个判断都不能少所以就是大于等于 
    if(left>=right)return; //没有指定区域可以分区比较排序

    //定义一个中轴值变量(已最左元素)为中心轴值
    int pivotValue=arr[left];

    //创建2个移动左右指针
    int moveLeftPoint=left;
    int moveRightPoint=right;


    //循环当前2个指针范围下的可以排序比较区域
    while(moveLeftPoint<moveRightPoint){


        //注意:由于是最左元素为中心轴值一开始一定要是先移动右指针,同理如果是最右为中心轴值 就要先移动左指针

        //先移动右指针
        while(moveLeftPoint<moveRightPoint&&arr[moveRightPoint]>=pivotValue){

            //符合当前条件,将当前右指针往前移动一位以此类推
            moveRightPoint--;
        }
        //将当前右指针的元素小于中轴值,就将右指针索引元素赋值给左指针索引上
        if(moveLeftPoint<moveRightPoint){
            arr[moveLeftPoint]=arr[moveRightPoint];
        }

        //移动左指针
        while(moveLeftPoint<moveRightPoint&&arr[moveLeftPoint]<pivotValue){

            //符合当前条件,将当前左指向后移动一位, 以此类推
            moveLeftPoint++;
        }
        //将当前左指针元素大于等中轴值 赋值给当前右指针索引上
        if(moveLeftPoint<moveRightPoint){
            arr[moveRightPoint]=arr[moveLeftPoint];
        }


    }

    //当2个指针相撞(索引相等)将中轴值元素赋值给当前索引上,这样中轴值左边区域都是小于中轴值的元素 右边区域都是大于等于中轴值元素 这是从小到大排列
    if(moveLeftPoint==moveRightPoint){
        arr[moveLeftPoint]=pivotValue;
    }

    //将当前中轴值左边区域进行分区排序
    quickSortPitFillDataVersion3(arr,left,moveLeftPoint-1);

    //将当前中轴值右边区域进行分区排序
    quickSortPitFillDataVersion3(arr,moveRightPoint+1,right);
}


//快速排序值数据挖坑法 以最右元素为中轴值
public static void quickSortPitFillDataVersion4(int []arr ,int left,int right){

    //判断当前是否有可比较排序区域,> 还是=取决于  是先移动左指针还是右指针 2个判断都不能少所以就是大于等于
    if(left>=right)return;

    //创建一个中轴值 以最右元素为中轴值
    int pivoteValue=arr[right];

    //创建2个可移动指针
    int moveLeftPoint=left;
    int moveRightPoint=right;

    //循环当前可比较排序区域
    while(moveLeftPoint<moveRightPoint){

        //由于当前是最右元素为中心轴所有先移动 左指针

        //移动左指针
        while(moveLeftPoint<moveRightPoint&&arr[moveLeftPoint]<pivoteValue){
            //指针想后移动一位 以此类推
            moveLeftPoint++;
        }

        //将当前左指针元素赋值给右指针索引上
        if(moveLeftPoint<moveRightPoint){
            arr[moveRightPoint]=arr[moveLeftPoint];
        }

        //移动右指针
        while(moveLeftPoint<moveRightPoint&&arr[moveRightPoint]>=pivoteValue){
            //将当前右指针向前移动一位 依次类推
            moveRightPoint--;
        }
        if(moveLeftPoint<moveRightPoint){
            arr[moveLeftPoint]=arr[moveRightPoint];
        }
    }

    //当前2个指针相撞(相等)
    if(moveLeftPoint==moveRightPoint){
        //将当前中轴值元素赋值给当前索引上
        arr[moveRightPoint]=pivoteValue;
    }

    //指针当前中轴值元素索引左边区域进行分区排序
    quickSortPitFillDataVersion4(arr,left,moveLeftPoint-1);

    //指针当前中轴值元素索引右边区域进行分区排序
    quickSortPitFillDataVersion4(arr,moveRightPoint+1,right);
}




//快速排序之挖坑填数法  中轴值为区域中的中心
public static void quickSortPitFillDataVersion5(int arr[],int left,int right){

    //判断当前2个指针对应的区域是否可以执行排序分区,> 还是=取决于  是先移动左指针还是右指针 2个判断都不能少所以就是大于等于
    if(left>=right) return;

    //创建一个中轴值
    int pivoteValue=arr[(left+right)/2];

    //创建2个可移动指针
    int moveLeftPoint=left;
    int moveRightPoint=right;
    
    int flag=true;

    //循环当前区域的的指针信息
    while(moveLeftPoint<moveRightPoint){

        //这里默认先移动左指针,
        while(moveLeftPoint<moveRightPoint&&arr[moveLeftPoint]<pivoteValue){
            //符合条件将左指针往后移动一位
            moveLeftPoint++;
        }
        if(moveLeftPoint<moveRightPoint){
            if(flag){
            	//默认第一次是将左索引数据添加在中心值对应索引的位置上
                arr[(left+right)/2]=arr[moveLeftPoint]
                flag=false;
            }else{
                arr[moveRightPoint]=arr[moveLeftPoint];
            }
        }

        //移动右指针
        while(moveLeftPoint<moveRightPoint&&arr[moveRightPoint]>=pivoteValue){
            moveRightPoint--;
        }
        if(moveLeftPoint<moveRightPoint){
            arr[moveLeftPoint]=arr[moveRightPoint];
        }
    }

    //当前2个指针相撞(相等)
    if(moveLeftPoint==moveRightPoint){
        //将当前中轴值元素赋值给当前索引上
        arr[moveRightPoint]=pivoteValue;
    }

    //指针当前中轴值元素索引左边区域进行分区排序
    quickSortPitFillDataVersion5(arr,left,moveLeftPoint-1);

    //指针当前中轴值元素索引右边区域进行分区排序
    quickSortPitFillDataVersion5(arr,moveRightPoint+1,right);

}
Publicado 18 artículos originales · ganado elogios 0 · Vistas 292

Supongo que te gusta

Origin blog.csdn.net/weixin_44698882/article/details/105074556
Recomendado
Clasificación