关于快速排序算法的一个实现

1.什么是快速排序

      快速排序的意思就是说,对于一个数组,随机从数组中选取一个值,然后将数组里的其他值与选中的值进行比较,小于选中的值的放在左侧,大于选中的值的,放在右侧。将选中的数放在中间。对于左边和右边的部分分别重复这个过程直到每次处理一个或者两个值,全部结束后认为排序完成。

2.算法实现

      一般情况下,选中的标准数就是数组的第一个元素(因为简单嘛,你完全可以选则最后一个数)我们定义两个指针,一个指向现在的这个目标元素,另外一个指向数组的最后一个元素。当我们选好目标数后,左边指针的这个位置的数就可以被替换了(因为这个数已经保存在目标数里了),可以认为,左边指针这里出现一个空挡。此时,移动右边指针,直到发现一个小于目标数的元素,这个数应该在目标数的左侧我们把它放在左边指针的空挡里。此时,右侧指针的位置也出现了一个空挡,移动左侧指针。。。依次轮流执行直到两个指针快要相遇。左边指针经过的地方都是小于等于目标数的,右边指针经过的地方都是大于等于目标数的。两个指针快要相遇时,有两种情况:
      1.右侧指针处有一个空挡,左侧指针在向右搜索,然后停在右侧指针的右侧某个位置。这种情况下,应该将目标数放在右侧指针位置,然后继续对左右两个半边进行递归。
      2.左侧指针处有一个空挡,...

    以下是实现算法:

public void quicksort(int []data,int begin,int end){
    int temp = data[begin],flag = 1;
    if(end-begin < 1) return;  // only one element
    if(end - begin == 1){       // only two elements
        if(data[begin]>data[end]){
            data[begin] = data[end];
            data[end] = temp;
        }
        return ;
    }
    int l = begin,r = end,m=0;
    while(l<=r){
        flag ^= 1;
        if(flag == 0){ // left empty, search right
            while(begin<=r && data[r]>=temp)
                r -= 1;
            if(r<=l){
                data[l] = temp;
                m = l;
                break;
            }
            data[l] = data[r];
        }else{         // right empty, search left
            while(end>=l && data[l]<=temp)
                l += 1;
            if(r<=l){
                data[r] = temp;
                m = r;
                break;
            }
            data[r] = data[l];
        }
    }
    quicksort(data,begin,m-1);
    quicksort(data,m+1,end);
}

3.一些改进

      以上就是本文一开始快速排序算法的代码实现,从代码中可以看出,程序每次运行一次,将有一个数字被排序好(即m),所以程序需要递归n次(不考虑递归结束的情况,实际值小于n)。如果在递归前,将目标数周围与目标数相等的数也默认排序完成,就可以提高该算法的效率。根据以上思想,修改程序如下:

public void quicksort(int []data,int begin,int end){
    int temp = data[begin],flag = 1;
    if(end-begin < 1) return;  // only one element
    if(end - begin == 1){       // only two elements
        if(data[begin]>data[end]){
            data[begin] = data[end];
            data[end] = temp;
        }
        return ;
    }
    int l = begin,r = end,m=0;
    while(l<=r){
        flag ^= 1;
        if(flag == 0){ // left empty, search right
            while(begin<=r && data[r]>=temp)
                r -= 1;
            if(r<=l){
                data[l] = temp;
                m = l;
                break;
            }
            data[l] = data[r];
        }else{         // right empty, search left
            while(end>=l && data[l]<=temp)
                l += 1;
            if(r<=l){
                data[r] = temp;
                m = r;
                break;
            }
            data[r] = data[l];
        }
    }
    l = m-1;
    while(begin<=l && data[l]==temp)
        l -= 1;
    r = m+1;
    whiel(r<=end && data[r] == temp)
        r += 1;
    quicksort(data,begin,l);
    quicksort(data,r,end);
}

4.快速排序的稳定性

      快速排序算法是不稳定的,原因在于:在两侧指针分别搜索时,无法保证元素的先后顺序。右侧的元素被移动到左侧,和左侧原来的元素之间的相对关系是随机的。因此,快速排序不是一种稳定排序的算法。

 

posted @ 2017-02-26 22:52  gukz  阅读(1477)  评论(0编辑  收藏  举报