Hoare快速排序的Partition实现

Hoare快速排序的Partition实现

伪代码

// 升序
Hoare_Partition(A, L, R)
x = A[L]
i = L, j = R

while i < j							// 循环一
	while i < j and A[j] <= x		// 循环二
		j--
	while i < j and A[i] >= x		// 循环三
		i++
	if i < j
		exchange A[j] with A[i]		// 交换一
		
exchange A[L] with A[i]				// 交换二

return i

解释

升序算法为例。
目的:返回一个数组下标 i,保证 A[L, L+1, ..., i-1] <= A[i]A[i+1, i+2, ..., R] >= A[i]
思想双指针

  • x:参考值(x = A[L]
  • j:从右往左遍历,寻找小于 xA[j]
  • i:从左往右遍历,寻找大于 xA[i]
  • 交换:若满足(i < j),则交换 A[j]A[i]。此操作保证大于 x 的元素在数组侧,小于 x 的元素在数组侧。(交换后,A[L, L+1, ..., i] <= xA[j, j+1, ..., R] >= x

注意
约定:如伪代码中注释所写,对各个循环和交换操作取一个名称。


1. 循环结束的两种情况:

  • i -> j
x = 5
5 3 4 2 7 5
  ^   ^
  i   j(已结束)

j 已结束循环二,即此时 A[j] < x
i3 开始遍历,直至 i == j,结束循环三。因不满足交换一的条件,所以结束循环一。
此时,A[i] 必然小于 x,未达到算法的目的。因此,进行交换二,使 A[i] == x,则达成目的。

  • j -> i
   5 4 3 7 10 5
       ^    ^
(已结束)i    j

i 已结束循环三,(因为 j 先遍历,所以)此时已经结束一轮循环(执行过交换一),A[i] 必然小于 x
j10 开始遍历,直至 i == j,结束循环三。因不满足交换一的条件,所以结束循环一。
显然,A[i] < x。因此,进行交换二,使 A[i] == x,则达成目的。


2. 为什么要令 i = L,且先遍历 j
:保证循环一结束时,满足以下三点:

  • 条件一A[i] <= x
  • 条件二A[L, L+1, ..., i-1] <= x
  • 条件三A[i+1, i+2, ..., R] >= x

同时满足三个条件,在循环一结束后,执行交换二,则达到算法的目的。

反例

1 2 3 4 5
^       ^
i       j
  • 假设一:i = L + 1
    循环一结束时,A[i] == 2 > x,违背条件一
  • 假设二:优先遍历 i
    循环一结束时,A[i] == 2 > x,违背条件一

3. 为什么三个循环结束的条件是 i < j

  • 循环一:若 i == j,则表明仅剩一个元素,自身就是排列好的。
  • 循环二:该循环可以令 i <= j
  • 循环三:防止循环一结束后出现 A[i] > x
    反例
x = 5
5 3 4 2 7 5
  ^   ^
  i   j(已结束)

i == j 仍执行循环三,则循环一结束时 A[i] == 7 > x,违背条件一。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值