排序算法之--快速排序(及优化测试亿级100_000_000用时)

该方法的基本思想是:

1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

挖坑填数+分治法:

对挖坑填数进行总结

1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。

2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。

3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。

4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。

 

第一版快排(数据100_000_00级的):

   //1.先从数列中取出一个数作为基准数。
    //2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
    //3.再对左右区间重复第二步,直到各区间只有一个数。

    public static void Quicksort(int [] arr,int left,int right)
    {
        if(arr.length<=1 || arr==null)
        {
            return;
        }
        if(left<right)
        {
            int mid=getmid(arr,left,right);
            Quicksort(arr,left,mid-1);
            Quicksort(arr,mid+1,right);
        }

    }

    //1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
    //2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
    //3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
    //4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
    public static int getmid(int [] arr,int left,int right)
    {
        int temp=arr[left];
        while (left<right)
        {
            //从右往左
            //最左边小于第一个数
            while (left<right && arr[right]>=temp)
            {
                right--;
            }
            //将最右边比基准数小的数移到左边
            arr[left]=arr[right];
            //从左往右
            //最右边大于第一个数
            while (left<right &&arr[left]<temp)
            {
                left++;
            }
            //将最左边比基准数大的移到右边
            arr[right]=arr[left];

        }
        arr[left]=temp;//基准元素归位
        return left;
    }

    public static void main(String[]arg)
    {
        //int [] ints =new int[]{12 ,9 ,8  ,1,2,7  , 1 , 2  ,3   , 6 };
        int[] ints=new int[100_000_00];
        for(int i=0;i<ints.length;i++){//随机产生数据
            ints[i]=(int)(Math.random()*1000+1);
        }
        System.out.println("程序运行时间:start" +  "ms");
        long startTime = System.currentTimeMillis();    //获取开始时间
        //show(ints);
        Quicksort(ints,0,ints.length-1);
        //show(ints);
        long endTime = System.currentTimeMillis();    //获取结束时间

        System.out.println("程序运行时间:" + (endTime - startTime) + "ms");    //输出程序运行时间
    }
    public static  void  show(int [] ints)
    {
        for(int i=0;i<ints.length;i++)
        {
            System.out.print(ints[i]+"  ");
        }
        System.out.println("");
    }

 

用时:

如果把数据加成100_000_000亿级的,会出现栈溢出!!

 分析:

第一版只是一般书上的快速排序,如果出现大量重复数据,在左右移动过程中就会浪费不少次数,所以,我们要在加一个变量限制。

第二版:

 public  static  void swap(   int [] arr, int low,int high)
      {
          int temp=arr[low];
          arr[low]=arr[high];
          arr[high]=temp;//数据交换
      }
    public  static  void Qsortplus(   int [] arr, int low,int high)
    {
        if(low <  high)
        {
            int lt=low;
            int gt=high;//左边,右边
            int i=low+1;//开始循环位置
            int temp=arr[low];//保存第一个数据
            while(i<=gt)//循环夹逼
            {
                if(arr[i]<temp) //小于
                {
                    swap(arr, lt,i);//移动
                    lt++;
                    i++;
                }
                else  if(arr[i]>temp)//大于
                {
                    swap(arr,i,gt);//移动
                    gt--;
                }
                else
                {
                    i++;
                }
            }
            Qsortplus(   arr, low,lt-1); 
            Qsortplus(    arr, gt+1,high);//分段
        }

    }
     public static void show(int[] args) 
     {
         
         for(int i=0;i<args.length;i++)
         {
             System.out.print(args[i]+" ");
         }
           System.out.println("");
     }

    public static void main(String[] args) 
    {
       // int [] arr=new int[]{4,1,2,9,4,6,4,2,4,3,4,1,7,4,7,4,7,7};
        int[] arr=new int[100_000_00];
        for(int i=0;i<arr.length;i++){//随机产生数据
            arr[i]=(int)(Math.random()*1000+1);
        }
        long startTime = System.currentTimeMillis();    //获取开始时间
        Qsortplus(    arr,0,arr.length-1);
       // show(arr) ;
        long endTime = System.currentTimeMillis();    //获取结束时间

        System.out.println("程序运行时间:" + (endTime - startTime) + "ms");    //输出程序运行时间

    }

用时:

测试亿级100_000_000用时:

哈哈 感觉好神奇

 

 

https://www.cnblogs.com/MOBIN/p/4681369.html

https://blog.csdn.net/morewindows/article/details/6684558

 

posted @ 2018-08-08 22:29  symkmk123  阅读(1106)  评论(0编辑  收藏  举报