自己写快速排序的几点问题

什么是快速排序

快速排序其实主要用到递归思想,冒泡排序是比较相邻两个数的大小,而快速排序是从所有数中找到一个标杆,从前到后和从后往前都是拿来和这个标杆去比较。比这个标杆小的放前面,大的放后面。然后以这个标杆为分界线分成两个部分再继续排,直到所有元素有序为止。

怎么理解快速排序

快速排序其实分为两个过程,一个是把数据分为左边比标杆小,右边比他大的两部分,另一个是重复前一个过程。而要想把数据变为左边都是较小,右边较大,需要几个步骤。首先找一个标杆值,我这里使用中间值作为标杆。然后数组下标从0到lenth-1递增,如果都是比标杆小的则加一(为什么是小于而不是等于后边会说),等找到不比标杆小的,进行数组下标从length-1到0递减的操作,如果都是大于标杆则减一,直到停止。然后把array[l]与array[h]。比如int [] array = new int[]{9, 4, 8,7}; 第一次操作之后array[l]为9,array[h]为4,l=0,h=2,交换后为{4, 9, 8,7},然后array[l]为4,array[h]为4,l=0,h=0,从array[0]分开,然后分为两部分,array[0]到array[0](已经有序)array[1]到array[3]{9,8,7}。以此类推,输出结果:
4,9,8,7,
4,7,8,9,
4,7,8,9,

快速排序的java实现代码

public class QuickSort
{
    public static void qsort( int low,int high,int array[])
    {
      if (high <=low || array == null || array.length <= 1)
       //数组为空,数组就一个元素或者左边下标大于右边等非法输入考虑
      {
          return;
      }

        int l=low;
        int h=high;
        int pivot=array[(low+high)/2]; //设定标杆值

        while (l<h)
        {   //l一直在h左边
            while ( array[h] >pivot)   //不能有等于 否则会导致h越界(所有值一样情况下,最左边值为标杆时)
            {
                --h;
            }
            while (array[l] <pivot)//不能有等于 否则会导致h越界(所有值一样情况下,最右边值为标杆时)
            {
                l++;
            }
            if (l < h)
            {
                int temp = array[l];
                array[l] = array[h];
                array[h] = temp;
//                 完成一轮,此时变为, 0, 4, 8, 2, 55, 3, 4, 8, 6, 4, 1, 11, 34, 90, 23, 54, 77, 9, 2, 9, 4, 10
                int i=1;  String out="";
                for(int re:array)
                {
                    out+=(re+",");
                }
                System.out.println(out);
//                i++;
//                System.out.println(i); 想输出 “第i次结果为多少”这种格式,可是i循环加不能用,所以就注释掉了

                l++;
                h--; // 继续进行与标杆对比的操作
            } else if (l == h)
            {
                l++; //此时左右下标汇合,意味着标杆左右侧大致分好了,下面是分别对左右进行排序,所以l+1,一次为右边部分开始下标。
            }
        }
            qsort(low,h,array);
            qsort(l,high,array);
    }

        public static  void main (String[] args)
        {
//            int [] array = new int[]{1, 4, 8, 2, 55, 3, 4, 8, 6, 4, 0, 11, 34, 90, 23, 54, 77, 9, 2, 9, 4, 10};
             int [] array = new int[]{9, 4, 8,7};
//           int [] array = new int[]{1,1,1,1}; //测试与标杆值对比的等于情况
             qsort(0,array.length-1,array); // 第一次把输入带进排序函数
             String out="";
             for(int re:array)   //循环输出数组值
             {
                 out+=(re+",");
             }
            System.out.println( "排序结果为");
             System.out.println(out);
        }
}

输出结果:

4,9,8,7,
4,7,8,9,
排序结果为
4,7,8,9,

0,4,8,2,55,3,4,8,6,4,1,11,34,90,23,54,77,9,2,9,4,10,
0,4,8,2,10,3,4,8,6,4,1,11,34,90,23,54,77,9,2,9,4,55,
0,4,8,2,10,3,4,8,6,4,1,4,34,90,23,54,77,9,2,9,11,55,
0,4,8,2,10,3,4,8,6,4,1,4,9,90,23,54,77,9,2,34,11,55,
0,4,8,2,10,3,4,8,6,4,1,4,9,2,23,54,77,9,90,34,11,55,
0,4,8,2,10,3,4,8,6,4,1,4,9,2,9,54,77,23,90,34,11,55,
0,4,2,2,10,3,4,8,6,4,1,4,9,8,9,54,77,23,90,34,11,55,
0,4,2,2,4,3,4,8,6,4,1,10,9,8,9,54,77,23,90,34,11,55,
0,4,2,2,4,3,4,1,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,4,3,4,4,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,6,4,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,10,9,8,9,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,9,9,8,10,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,9,8,9,10,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,54,77,23,90,34,11,55,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,54,77,23,55,34,11,90,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,11,77,23,55,34,54,90,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,11,23,77,55,34,54,90,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,11,23,54,55,34,77,90,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,11,23,54,34,55,77,90,
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,11,23,34,54,55,77,90,
排序结果为
0,1,2,2,3,4,4,4,4,6,8,8,9,9,10,11,23,34,54,55,77,90,

实现中的几个问题

下标移动问题

如上面所说,快速排序其实是左右下标都移动,同时在找到符合值并相互交换后,是需要把左右下边分别加减,然后再继续寻找的。

特殊输入情况的考虑

if (high <=low || array == null || array.length <= 1)
   //数组为空,数组就一个元素或者左边下标大于右边等非法输入考虑

下标越界情况

while ( array[h] >pivot)   //不能有等于 否则会导致h越界(所有值一样情况下,最左边值为标杆时)

这里我一开始写的时候没注意,写了等于,但是后来运行发现有下标越界错误。然后就想了想如果是全相等情况,那下标会一直减或者加,必然会越界。其实全相等是特殊情况,那就是最左边的值为标杆或者与标杆相等时,就会导致出现下标-1(右边也一样会超出最大值)。这个是我这种算法会出现的情况,别的实现不是很清楚是否这样。所以程序里等于这种判断需要谨慎,得想下特殊情况会怎样,避免导致出错。

参考资料:维基百科快速排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值