785. 快速排序

Problem: 785. 快速排序

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • Code
    • 方法一(调用系统类库)
    • 方法二(随机快速排序经典版)
    • 方法三 (利用荷兰国旗问题改写快排)

思路

这个问题要求实现快速排序算法,对给定的整数数组进行从小到大的排序。 快速排序算法的工作原理是从数组中选择一个“枢轴”元素,然后将其他元素分区为两个子数组,一个包含小于枢轴的元素,另一个包含大于枢轴的元素。然后通过对两个子数组递归调用快速排序算法进行排序。
快速排序的时间复杂度在最好和平均情况下为O(n log n),在最坏情况下为O(n^2),但对于大多数输入,最坏情况并不常见。空间复杂度为O(log n)到O(n),取决于快速排序的版本,并假设不计算存储输入所需的空间。

解题方法

  1. 方法一(调用系统类库):这种方法是最简单的,直接调用Java的Arrays.sort()方法对数组进行排序。
  1. 方法二(随机快速排序经典版):这种方法是快速排序的经典实现,通过随机选择一个元素作为枢轴,然后将数组分为两部分,一部分是小于枢轴的元素,另一部分是大于枢轴的元素,然后对这两部分分别进行快速排序。
  1. 方法三(利用荷兰国旗问题改写快排):这种方法是快速排序的一个变种,通过将数组分为三部分,一部分是小于枢轴的元素,一部分是等于枢轴的元素,一部分是大于枢轴的元素,然后对小于枢轴和大于枢轴的两部分分别进行快速排序。

复杂度

时间复杂度:

时间复杂度在最好和平均情况下是 O ( n l o g n ) O(n log n) O(nlogn),在最坏情况下是 O ( n 2 ) O(n^2) O(n2)

空间复杂度:

空间复杂度是 O ( l o g n ) O(log n) O(logn)

Code

方法一(调用系统类库)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int n;
	static int MAXN = 100001;
	static int[] arr = new int[MAXN];
	public static void main(String[] args) throws IOException {
		n = nextInt();
		for(int i = 0; i < n; i++) {
			arr[i] = nextInt();
		}
		Arrays.sort(arr, 0, n);
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i < n; i++) {
			sb.append(arr[i]);
			sb.append(" ");
		}
		out.println(sb);
		out.flush();	
	}
	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

方法二(随机快速排序经典版)

未通过所有样例,这种方法不推荐

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int n;
	static int MAXN = 100001;
	static int[] arr = new int[MAXN];

	public static void main(String[] args) throws IOException {
		n = nextInt();
		for (int i = 0; i < n; i++) {
			arr[i] = nextInt();
		}
		quickSort(0, n - 1);
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < n; i++) {
			sb.append(arr[i]);
			sb.append(" ");
		}
		out.println(sb);
		out.flush();

	}

	public static void quickSort(int l, int r) {
		if (l >= r) {
			return;
		}
		int x = arr[l + (int) (Math.random() * (r - l + 1))];
		int mid = partition(l, r, x);
		quickSort(l, mid - 1);
		quickSort(mid + 1, r);
	}

	private static int partition(int l, int r, int x) {
		int a = l, xi = 0; // 记录等于x的位置
		for (int i = l; i <= r; i++) {
			if (arr[i] <= x) {
				swap(a, i);
				if (arr[a] == x) {
					xi = a;
				}
				a++;
			}
		}
		swap(xi, a - 1);
		return a - 1;
	}

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

	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

方法三 (利用荷兰国旗问题改写快排)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int n;
	static int MAXN = 100001;
	static int[] arr = new int[MAXN];

	public static void main(String[] args) throws IOException {
		n = nextInt();
		for (int i = 0; i < n; i++) {
			arr[i] = nextInt();
		}
		quickSort(0, n - 1);
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < n; i++) {
			sb.append(arr[i]);
			sb.append(" ");
		}
		out.println(sb);
		out.flush();

	}

	public static int first, last;
	public static void quickSort(int l, int r) {
		if(l >= r) {
			return;
		}
		int x = arr[l + (int) (Math.random() * (r - l + 1))];
		partition(l, r, x);
		quickSort(l, first - 1);
		quickSort(last + 1, r);
	}

	private static void partition(int l, int r, int x) {
		if(l >= r) {
			return;
		}
		first = l;
		last = r;
		int i = l;
		while(i <= last) {
			if(arr[i] == x) {
				i++;
			} else if(arr[i] < x) {
				swap(i++, first++);
			} else {
				swap(i, last--);
			}
		}
		
	}

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

	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

你可能感兴趣的:(算法,算法,排序算法,数据结构)