非递归快速排序

递归的算法通过栈很容易转化为非递归的算法,方法一是利用栈编写非递归快速排序算法。

 

方法二是利用数组分别记录需要排序的区间的起点和终点。

 

方法三是通过为每个位置选择合适的数从而达到排序的目的。代码如下所示。

 

    /**
     * partition方法
     *
     * @param digits
     * @param low
     * @param high
     * @return
     */
    public int partition20140419(int[] digits, int low, int high)
    {
        int pivot = digits[low];
        while (low < high) {
            while ((low < high) && (digits[high] >= pivot)) {
                --high;
            }
            digits[low] = digits[high];
            while ((low < high) && (digits[low] <= pivot)) {
                ++low;
            }
            digits[high] = digits[low];
        }
        digits[high] = pivot;
        return high;
    }

    /***********************************************************
     * 非递归快排,基本思想是为每个位置找到合适的数
     *
     * @param digits
     * @param len
     */
    public void quickSort20140419(int[] d, int len)
    {
        int[] b = new int[len];
        for (int i = 0; i < len; ++i) {
            b[i] = -1;
        }
        boolean finished = false;
        while (!finished) {
            int i;
            // 找一个最小的下标位置使得这个位置还没有找到合适的数
            for (i = 0; i < len; ++i) {
                if (b[i] > 0) {
                    continue;
                }
                int pivot = partition20140419(d, i, len - 1);
                b[pivot] = d[pivot];
                break;
            }
            if (i == len) {
                finished = true;
            }
        }
        for (int i = 0; i < len; ++i) {
            d[i] = b[i];
        }
    }

    /**
     * 测试方法quickSort20140419
     */
    public void testQuickSort20140419()
    {
        System.out.println("------开始测试函数testQuickSort20140419()------");
        int n = 10;
        int[] digits = new int[n];
        for (int i = 0; i < n; i++) {
            digits[i] = n - i;
        }
        System.out.println("排序之前的数组是:");
        for (int i = 0; i < n; i++) {
            System.out.print(digits[i] + ", ");
        }
        System.out.println();
        quickSort20140419(digits, n);
        System.out.println("排序之后的数组是:");
        for (int i = 0; i < n; i++) {
            System.out.print(digits[i] + ", ");
        }
        System.out.println();
    }

  当然,还可以限制partition区间的终点提高效率。前面方法的时间复杂度为O(nlogn),因为需要为每个位置全部数组进行partition。

  改进的方法之一是利用已经partition出来的位置来缩短partition的区间。   


    /***********************************************************
     * 非递归快排,基本思想是为每个位置找到合适的数
     *
     * @param digits
     * @param len
     */
    public void quickSort20140421(int[] d, int len)
    {
        int[] b = new int[len];
        for (int i = 0; i < len; ++i) {
            b[i] = -1;
        }
        boolean finished = false;
        int minIndex = 0; // 找一个最小的下标位置使得这个位置还没有找到合适的数
        int maxIndex = len;
        while (!finished) {
            int pivot = partition20140419(d, minIndex, maxIndex - 1);
            b[pivot] = d[pivot];
            int i;
            for (i = 0; i < len; ++i) {
                if (b[i] < 0) {
                    minIndex = i;
                    break;
                }
            }
            if (i == len) {
                finished = true;
            }
            if (!finished) {
                maxIndex = minIndex;
                for (i = minIndex; i < len; ++i) {
                    if (b[i] >= 0) {
                        maxIndex = i;
                        break;
                    }
                }
                if (i == len) {
                    maxIndex = len - 1;
                }
            }
        }
        for (int i = 0; i < len; ++i) {
            // System.out.print(b[i] + ", ");
            d[i] = b[i];
        }
    }

    /**
     * 测试方法quickSort20140421
     */
    public void testQuickSort20140421()
    {
        System.out.println("------开始测试函数testQuickSort20140421()------");
        int n = 10;
        int[] digits = new int[n];
        for (int i = 0; i < n; i++) {
            digits[i] = n - i;
        }
        System.out.println("排序之前的数组是:");
        for (int i = 0; i < n; i++) {
            System.out.print(digits[i] + ", ");
        }
        System.out.println();
        // quickSort20120714(digits, 2, n - 1);
        quickSort20140421(digits, n);
        System.out.println("排序之后的数组是:");
        for (int i = 0; i < n; i++) {
            System.out.print(digits[i] + ", ");
        }
        System.out.println();
    }

posted @ 2014-04-19 13:48  小塘百炼  阅读(285)  评论(0)    收藏  举报