数据结构-排序-快速排序之固定位置选取基准法(递归/非递归)

版权声明:中华人民共和国持有版权 https://blog.csdn.net/Fly_Fly_Zhang/article/details/84994155

快速排序: 数据量小的时候,使用插入排序;聚焦相同基准元素法

  • 固定位置选取排序:数据越有序,复杂度越高
  • 随机选取基准排序
  • 三分取中法

思想:均匀的分割待排序序列 :选取一个基准par,定义两个指针 low high 一般基准选取low下标的值;如果high下标的值比par大,high–;反之将high的值放到low 下标; low的操作和high 一样 ;当high和low 相遇时,将par放到low角标,此时,左边全是比par小的,右边全是比par 大的;

快速排序:递归实现 ,一趟排序结束后如果基准左右两边的元素数量大于等于2,那么说明左右还没有有序,那么在确定新的low 和high的值 继续调用此方法;

public static int partion(int []array ,int low,int high){    //一趟快速排序;
          int tmp=array[low];
          while(low<high){
                   while(low<high&& array[high]>tmp){  //如果high对应的元素大于tmp;
                           high--;  
                     }
                    if(low >= high) {
                         break;
                    } else {
                      array[low] = array[high];
                    }
                     while(low < high && array[low] <= tmp) {
                         low++;
                    }
                     if(low >= high) {
                          break;
                    } else {
                          array[high] = array[low];
                    }
        }
        array[low] = tmp;
        return low;
        }
         /**
     * 时间复杂度:O(nlog2n)
     * 空间复杂度:O(log2n)
     * 稳定性:不稳定
     * @param array
     * @param low
     * @param high
     */
      public static  void  quick(int [] array ,int low,int high ){
            int par=partion(array,low,high); 返回下一趟排序的基准;
            if(par>low+1){  //新的基准与边界之间的元素大于等于两个就可以确定新的par
            quick(array,low,par-1); //log 2 N;   基准左边递归
            }
            if(par<high-1){
               quick(array ,par+1,high); //右边递归。
            }
     }
     public static void  quickSort(int array){
          quick(array,0,array.length-1);
     }
       public static void main(String[] args) {
        int[] array = new int[10000];//n   log2n
        Random random = new Random();
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(10000)+1;
        }
        System.out.println(System.currentTimeMillis());
        quickSort(array);
        System.out.println(System.currentTimeMillis());
        System.out.println(Arrays.toString(array));
    }

快速排序: 非递归解法 :思想和递归解法差不多,只不过左右两边没有序,将新的low和high压入模拟栈中;在调用确定基准并排序的方法;只要栈不为空,那么就需要进行排序

public class TestQuickSort {
    //一趟快速排序函数
    public static int partion(int[] array,int low,int high) {
        int tmp = array[low];
        while(low < high) {
            while(low < high && array[high] >= tmp) {
                high--;
            }
            if(low >= high) {
                break;
            } else {
                array[low] = array[high];
            }
            while(low < high && array[low] <= tmp) {
                low++;
            }
            if(low >= high) {
                break;
            } else {
                array[high] = array[low];
            }
        }
        array[low] = tmp;
        return low;
    }
    public static void quickSort(int [] array){
            int high=array.length-1;
            int low=0;
            int par=partion(array,low,high);
            int size=(int)(Math.log(double)array.length/Math.log2d+1);  //这里如果闲麻烦可以直接将长度确定为array 的长度;
            int []  stack=new int [size*3]  //log2n
            //按理应该是*2  但是溢出,所以*3 。 可以直接放array的长度;
            int  top=0;
            if(par>low+1){   //先压第一次循环后符合条件的,在进循环
                  stack[top++]=low; 先入后出
                  stack[top++]=par-1;
            }
            if(par<high-1){
                 stack[top++]=par+1;
                 stack[top++]=high;
            }
            while(top>0){  //每次出一对low high 排序
                  high=stack[--top]; //后进先出
                  low=stack[--top];
                  par=partion(array,low,high);//调用一次快排确定新的基准
                   if(par>low+1){   
                  stack[top++]=low; 先入后出
                  stack[top++]=par-1;
                 }
                if(par<high-1){
                 stack[top++]=par+1;
                 stack[top++]=high;
                }
            }
    }
     public static void main(String[] args) {
        int[] array = new int[10000];//n   log2n
        Random random = new Random();
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(10000)+1;
        }
        System.out.println(System.currentTimeMillis());
        quickSort(array);
        System.out.println(System.currentTimeMillis());
        System.out.println(Arrays.toString(array));
    }
}

猜你喜欢

转载自blog.csdn.net/Fly_Fly_Zhang/article/details/84994155