随机快速排序

测试链接:

912. 排序数组 - 力扣(LeetCode)

随即快排java代码(acm版本):

public class QuickSort {

    public static int MAXN = 100001;
    public static int[] arr = new int[MAXN];
    public static int n;
    public static void main(String[] args) {
        BufferedReader br = new BufferdReader(new InputStreamReader(System.in));
        StreamTokenizer in = new StreamTokenizer(br);
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();
        n = (int) in.nval;
        for (int i = 0; i < n; i++) {
            int.nextToken();
            arr[i] = (int) in.nval;
        }
        quickSort2(0, n - 1);
        for (int i = 0; i < n - 1; i++) {
            out.print(arr[i] + " ");
        }
        out.println(arr[n-1]);
        out.flush();
        out.close();
        br.close();
    }

    // 随机快速排序经典版(不推荐)
	// 甚至在洛谷上测试因为递归开太多层会爆栈导致出错
    public static void quickSort1(int l, int r) {
        if (l == r) {
            return;
        }
        //l.....r随机选一个位置,x这个值,做划分
        int x = arr[l + (int)(Math.random() * (r - l + 1))];
        int mid = partition1(l, r, x);
        quickSort1(l, mid - 1);
        quickSort1(mid + 1, r); 
    }

    //partition1时间复杂度O(n)
    pulic static int partition1(int l, int r, int x) {
        //a: arr[l....a-1]范围是<=x的区域
        int a = l, xi;
        for(i = l; i <= r; i++) {
            if (arr[i] <= x) {
                swap(a, i);
                if (arr[i] = x) {
                    xi = a;
                }
                a++;
            }
        }
        swap(a-1, xi);
        return a-1;
    }

    //快速排序改进版
    public static void quickSort2(int l, int r) {
        if (l == r) {
            return;
        }
        //l.....r随机选一个位置,x这个值,做划分
        int x = arr[l + (int)(Math.random() * (r - l + 1))];
        partition2(l, r, x);

        // 为了防止底层的递归过程覆盖全局变量
		// 这里用临时变量记录first、last
        int left = first;
        int right = last;
        quickSort2(l, left - 1);
        quickSort2(right + 1, r); 
    }
    

    //荷兰国旗问题
    public static int first;
    public static int last;
    
    // 已知arr[l....r]范围上一定有x这个值
	// 划分数组 <x放左边,==x放中间,>x放右边
	// 把全局变量first, last,更新成==x区域的左右边界
    // partition2时间复杂度O(n)
    public static void partition2(int l, int r, int x) {
        first = l;
        last = r;
        while (i <= last) {
			if (arr[i] == x) {
				i++;
			} else if (arr[i] < x) {
				swap(first++, i++);
			} else {
				swap(i, last--);
			}
		}
    }    

    public static void swap(int i int j) {
        int temp;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
}

最差情况下时间复杂度:O(n^2),每次随机的数字在数组两个端点。

最好情况下时间复杂度:O(n*logn),根据master公式算出,每次随机的数字正好在数组中间。

因此随机快排时间复杂度:O(n*logn)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值