美文网首页
排序——快排/归并(nlgn)

排序——快排/归并(nlgn)

作者: 柚子过来 | 来源:发表于2018-10-17 21:17 被阅读0次

快速排序一般是递归实现,但是递归有一个问题就是如果递归太深会导致栈溢出,而大部分的递归实现都有对应的非递归解决方案,快排也不例外,代码中就给出了快速排序的递归与非递归实现。

package sort;

import java.util.Arrays;
import java.util.Stack;

public class NLgn_Sort {

/**
 * 利用快速排序查找数组第k大的元素
 * @param array
 * @param begin
 * @param end
 * @param k
 * @return
 */
public static int quickSort(int[] array, int begin, int end, int k) {
    if (begin >= end) {
        return -1;
    }

    int index = array[end];
    int i = begin, j = end;
    while (i < j) {

        while (i < j && array[i] < index) {
            i++;
        }
        if (i < j) {
            array[j--] = array[i];
        }

        while (i < j && array[j] > index) {
            j--;
        }
        if (i < j) {
            //最后一步赋值的是array[j],所以white循环走完时中间位置是j
            array[i++] = array[j];
        }

    }

    array[j] = index;
    if (j == k) {
        return index;
    }

    if (j < k) {
        return quickSort(array, j + 1, end, k);
    } else {
        return quickSort(array, begin, j - 1, k);
    }
}

public static void main(String[] args) {
    int[] a = {6, 5, 4, 3, 2, 1};
    System.out.println("quickSort:" + quickSort(a, 0, a.length - 1, 4));

    int[] b = {6, 5, 4, 3, 2, 1,5, 4, 3, 2, 1,5, 4, 3, 2, 1,5, 4, 3, 2, 1,5, 4, 3, 2, 1,5, 4, 3, 2, 1,};
    Non_recursion_quickSort(b);
    Arrays.asList(b).forEach(System.out::println);
}


/**
 * 快速排序的非递归实现
 * ---利用栈实现
 *        因为快速排序的原理就是每趟排序根据上下边界查找一个中间值,所以可以使用栈来保存上下边界
 * @param array
 */
public static void Non_recursion_quickSort(int[] array) {
    int len = array.length;
    if (len <= 1) {
        return;
    }
    Stack<Integer> stack = new Stack<>();
    int start = 0, end = len - 1;
    stack.push(end);
    stack.push(start);
    int middle;
    while (!stack.isEmpty()) {
        start = stack.pop();
        end = stack.pop();
        middle = quickSort_find_middle(start, end, array);
        if (middle > start) {
            stack.push(middle-1);
            stack.push(start);
        }
        if (middle < end) {
            stack.push(end);
            stack.push(middle+1);
        }
    }
}

/**
 * 快速排序一遍排序获取中间值的核心代码
 * @param start
 * @param end
 * @param array
 * @return
 */
private static int quickSort_find_middle(int start, int end, int[] array) {
    if (start == end) {
        return start;
    }
    int index = array[end];
    while (start < end) {
        while (array[start] < index && start < end) {
            start++;
        }

        if (start < end) {
            array[end] = array[start];
            end--;
        }

        while (array[end] > index && start < end) {
            end--;
        }

        if (start < end) {
            array[start] = array[end];
            start++;
        }

    }
    array[end] = index;
    return end;
}

}

相关文章

网友评论

      本文标题:排序——快排/归并(nlgn)

      本文链接:https://www.haomeiwen.com/subject/wlkdzftx.html