快速排序

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

参考地址:维基百科 

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

1、源代码

/**
     * 数据结构上学的快速排序
     * 
     * @param array
     *            待排序数组
     * @param left
     *            左边序号
     * @param right
     *            右边序号
     */
    public static void quickSortInDataStructure(int[] array, int left, int right) {
        if (left < right) {
            int key = array[left];
            int low = left;
            int high = right;
            while (low < high) {
                while (low < high && array[high] >= key) {
                    high--;
                }
                 
                while (low < high && array[low] <= key) {
                    low++;
                }
                 
                if (low < high)
                {
                    int temp = array[low];
                    array[low] = array[high];
                    array[high] = temp;
                }
            }

            array[left] = array[low];
            array[low] = key;
            System.out.println("键Key:" + key + ",结果:" + Arrays.toString(array));
            quickSortInDataStructure(array, left, low - 1);
            quickSortInDataStructure(array, low + 1, right);
        }
    }

2 测试代码

    @Test
    public void testQuickSortInDataStructure() {
        int[] array = { 1, 8, 3, 5, 4, 6, 2, 7, 9 };
        int[] expectResult = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        Sort.quickSortInDataStructure(array, 0, array.length - 1);
        Assert.assertArrayEquals(expectResult, array);
    }

3 结果

键Key:1,结果:[1, 8, 3, 5, 4, 6, 2, 7, 9]
键Key:8,结果:[1, 7, 3, 5, 4, 6, 2, 8, 9]
键Key:7,结果:[1, 2, 3, 5, 4, 6, 7, 8, 9]
键Key:2,结果:[1, 2, 3, 5, 4, 6, 7, 8, 9]
键Key:3,结果:[1, 2, 3, 5, 4, 6, 7, 8, 9]
键Key:5,结果:[1, 2, 3, 4, 5, 6, 7, 8, 9]

4 封装

4.1 封装java代码

package better.amy.sort;

import java.util.Comparator;
import java.util.Random;

/**
 * 快速排序
 * 
 * @author zhujinrong
 * 
 */
public class QuickSort {

    /**
     * 随机
     */
    public static final Random RND = new Random();

    /**
     * array[i]和array[j]进行交换
     * 
     * @param array
     * @param i
     * @param j
     */
    private static void swap(Object[] array, int i, int j) {
        Object temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    /**
     * 找到中轴
     * 
     * @param array
     * @param begin
     * @param end
     * @param cmp
     * @return 中轴位置
     */
    private static <E> int partition(E[] array, int begin, int end,
            Comparator<? super E> cmp) {
        int index = begin + RND.nextInt(end - begin + 1);
        E pivot = array[index];
        swap(array, index, end);
        for (int i = index = begin; i < end; ++i) {
            if (cmp.compare(array[i], pivot) <= 0) {
                swap(array, index++, i);
            }
        }

        swap(array, index, end);

        return (index);
    }

    /**
     * 快速排序
     * 
     * @param array
     * @param begin
     * @param end
     * @param cmp
     */
    private static <E> void qsort(E[] array, int begin, int end,
            Comparator<? super E> cmp) {
        if (begin < end) {
            int index = partition(array, begin, end, cmp);
            qsort(array, begin, index - 1, cmp);
            qsort(array, index + 1, end, cmp);
        }
    }

    /**
     * 快速排序入口
     * 
     * @param array
     * @param cmp
     */
    public static <E> void sort(E[] array, Comparator<? super E> cmp) {
        qsort(array, 0, array.length - 1, cmp);
    }
}

这个是在维基百科上的代码,我觉得写得非常好,以至于我把它补到这里来了。

4.2 测试代码

    @Test
    public void test100()
    {
        Integer [] array1 = new Integer[100];
        Integer [] array2 = new Integer[100];
        for(int i = 0; i < 100; i++)
        {
            array1[i] = new Random().nextInt(101);
            array2[i] = array1[i];
        }
        
        QuickSort.sort(array1, new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                // TODO Auto-generated method stub
                return o1.intValue() - o2.intValue();
            }
        });
        
        Arrays.sort(array2);
        
        Assert.assertArrayEquals(array2, array1);
     }

 5 总结与分析

  1、写java要有面向对象的思维跟封装特性,别脱不了C语言的想法。

  2、我看数据结构的算法和java面向对象的算法,有一点不同,就是在找中轴的位置的时候,一个是挨着找,一个是随机找的。这个我再看看两者有什么不同。

 

posted on 2014-12-26 13:52  BestNow  阅读(249)  评论(0编辑  收藏  举报

导航