数据结构与算法(十)—— 快速排序

该Java代码示例展示了如何在数组中找到第K大的元素并实现快速排序算法。程序首先定义了一个数组,然后通过自定义的kthLarge方法寻找数组中的第K大元素,接着对整个数组进行快速排序。快速排序方法采用了分治策略,通过分区操作找到分区点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class Demo {

	public static void main(String[] args) {
		int[] a = { 6, 0, 5, 4, 7, 2, 1 };
		// int[] a = { 0, 1, 2, 4, 5, 6, 7 };
		// int[] a = { 7, 6, 5, 4, 2, 1, 0 };
		print(a);

		// 求第K大元素
		int k = 3;
		int kthLarge = kthLarge(a, k);
		System.out.println("kthLarge=" + kthLarge);
		
		// 快速排序
		quickSort(a);
		print(a);
	}

	/************************** 求第K大元素 ********************************/
	public static int kthLarge(int[] a, int k) {
		if (a == null || a.length < k) {
			return -1;
		}
		/*
		 * 解题原理:
		 * 1. 将数组从大到小原地分区,分成三部分,A[0...p-1]、A[p]、A[p+1...n-1];左边逗比A[p]大,右边都比A[p]小
		 * 2. 分区之后:
		 *   - 如果 p+1 = k,那么A[p]就是要求的元素;
		 *   - 如果 p+1 < k,那么A[p]就落在[p + 1] 到 [n - 1]区间;反之则落在[0] 到 [p - 1] 区间
		 */
		int p = partition0(a, 0, a.length - 1);
		while (p + 1 != k) {
			if (p + 1 < k) {
				p = partition0(a, p + 1, a.length - 1);
			} else {
				p = partition0(a, 0, p - 1);
			}
		}
		return a[p];
	}

	/************************** 快速排序 ********************************/

	// 快速排序
	static void quickSort(int[] a) {
		quickSort0(a, 0, a.length - 1);
	}

	static void quickSort0(int[] a, int l, int r) {
		if (l >= r) {
			return;
		}
		// 升序
		int p = partition(a, l, r);
		// 降序
		// int p = partition0(a, l, r);
		quickSort0(a, l, p - 1);
		quickSort0(a, p + 1, r);
	}

	// 获取分区点(降序)
	static int partition(int[] a, int l, int r) {
		int p = a[r];
		// 比p小的序列
		int i = l;
		// 从整个数组中,遍历获取比p小的序列放到l~i中
		for (int j = l; j < r; ++j) {
			if (a[j] < p) {
				if (i == j) {
					++i;
				} else {
					int tmp = a[i];
					a[i++] = a[j];
					a[j] = tmp;
				}
			}
		}
		a[r] = a[i];
		a[i] = p;
		return i;
	}

	// 获取分区点(升序)
	static int partition0(int[] a, int l, int r) {
		int p = a[r];
		// 比p小的序列
		int i = l;
		// 从整个数组中,遍历获取比p小的序列放到l~i中
		for (int j = l; j < r; ++j) {
			if (a[j] > p) {
				if (i == j) {
					++i;
				} else {
					int tmp = a[i];
					a[i++] = a[j];
					a[j] = tmp;
				}
			}
		}
		a[r] = a[i];
		a[i] = p;
		return i;
	}

	/************************** 打印 ********************************/
	static void print(int[] a) {
		StringBuilder s = new StringBuilder();
		for (int i : a) {
			if (s.length() == 0) {
				s.append(i);
			} else {
				s.append(",").append(i);
			}
		}
		System.out.println(s.toString());
	}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值