快速排序

package sort;

import java.util.Scanner;

public class 快排 {
    private  static void sort(int x,int y,int[] a){
        int i,j,k,t,l;
        i=x;
        j=y;
        k=a[(i+j)/2];
        do{ 
             while ( (i<j) && (a[i]<k)) { i++;}
             while ( (i<j) && (a[j]>k) ) { j—;}
             if (i<j) {
                 t=a[i]; a[i]=a[j];a[j]=t; 
             }
        }while  (i<j);
        if i-1>x)   {   sort(x,i-1,a);  }
        if (j+1<y)  {   sort(j+1,y,a); }
        
    }
    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        //System.out.println("输入元素个数N:=");
        int n=read.nextInt();
        int a[];
        a=new int[n];
        for (int i=0;i<n;i++)
            a[i]=read.nextInt();
        sort(0,n-1,a);
        for (int i=0;i<n;i++)
            System.out.print(a[i]+"  ");
        }
}

    快排原理是分治思想,其中随机化快排最快。这段代码是错误的,是我一开始的代码,我改了很久,发现其中有几点值得关注。

    问题一:一个是a[I],a[j]与k的比较有没有等号的问题。

    问题二:离开do while循环时,I=j对应的值是否为k的问题。

    先说第一个,假设存在等号,那会出现什么情况,看这组数据--------

    10

    1 1 4 4 6 6 2 2 3 3

    当第一次执行时,k=6,然而执行完,I=j=9;直接出现问题二,也就是说,如果有等号,那么离开的时候,I=j对应的值就不一定是k,也就是说,你接下来的分治有问题。(分治是基于k已经定位好,且以k为中心进行划分)

    那么如何解决这个问题呢,大家踊跃留言吧...(我暂时没想到在保留等号下的快排算法)

    我们继续看,当没等号的时候,又会出现什么情况。

    先看这组数据:

    7

    1 4 3 4 1 4 8

    这组数据会导致死循环,问题出在哪里呢?还是相等问题,当k值在数列中多次出现,就可能出现这种情况。

    一开始我的解决方案是在a[I]a[j]交换后加I++,j—;

    但事实是,可能出现第一次所提到的问题二。

    总是有问题二出现,事实上,它也是这个算法成立的基础条件,既然你这么重要,那我给你加个标记,省的你乱跑找不到。于是我写了这个代码:

package sort;

import java.util.Scanner;

public class 快排 {
    private  static void sort(int x,int y,int[] a){
        int i,j,k,t,l;
        i=x;
        j=y;
        l=(i+j)/2;
        k=a[l];
        do{ 
             System.out.print(i+"  "+j+"  "+k+"------");
             while ( (i<j) && (a[i]<k)) { i++;}
             while ( (i<j) && (a[j]>k) ) { j--;}
             System.out.println(i+"  "+j+"  "+k); 
           if (i<j) {
               if (a[i]==k ) l=j;
               if (a[j]==k) l=i;
               t=a[i]; a[i]=a[j];a[j]=t; 
               i++;
               j--;
           }
        
        }while  (i<j);
        if (l-1>x)   {   sort(x,l-1,a);  }
        if (l+1<y)  {   sort(l+1,y,a); }
        
    }
    public static void main(String[] args) {
        Scanner read = new Scanner(System.in);
        int n=read.nextInt();
        int a[];
        a=new int[n];
        for (int i=0;i<n;i++)
            a[i]=read.nextInt();
        sort(0,n-1,a);
        for (int i=0;i<n;i++)
            System.out.print(a[i]+"  ");
        }
}

    这段代码基本解决了了刚才所提到的问题,暂时还没找到错误的数据,如果大家有更简洁的代码,记得分享一下。

posted on 2015-03-25 12:30  大大东  阅读(156)  评论(0编辑  收藏  举报

导航