快速排序实践经验总结:弄透其逻辑

快速排序的思想其实比较好理解,但是实际码代码的时候,会遇到一些问题,并不是想象的那么简单。
在网上看了一下,感觉大多数的博客介绍其排序原理的时候说得很生动形象,但给出的实现代码其实逻辑说得不是很清晰,甚至是错误的。
这里我自己写了一下快速排序,过程中也遇到了一些问题,但总算是解决了。这里给出来,并详细说一下其逻辑。

(1) Quick.h 头文件
#pragma once

#include "stdafx.h"


using namespace std;

class Quick
{
public:
	Quick(vector<int> a);

	void sort();

	bool isSorted();

	void show();

private:

	vector<int> v;
	int N;
	
	void exch(int i, int j);

	int position(int lo, int hi);

	void sort(int lo, int hi);
};

(2) Quick.cpp 具体实现
#include "stdafx.h"
#include "Quick.h"

using namespace std;

Quick::Quick(vector<int> a) : v(a)
{
	N = v.size();
}


void Quick::sort()
{
	sort(0, N - 1);
}

void Quick::sort(int lo, int hi)
{
	// random array
	if (hi <= lo)	return;

	int j = position(lo, hi);
	exch(lo, j);
	sort(lo, j - 1);
	sort(j + 1, hi);
}

int Quick::position(int lo, int hi)
{
	int i = lo , j = hi+1;	// 注意其起点
	int base = v[lo];
	while (1)
	{
		while (v[--j] > base);	//就算j移到了 lo,也会因为v[j]==v[lo]==base,而退出此循环
		while (v[++i] < base)	if(i==j) break;
		// base右侧的数组有3种情况:
		// (1) 均大于base;	则j会移动到lo,i递增1次后结束;此时j<i。不需要exch(i,j),且要直接退出while(1)
		// (2) 均小于base;	则j递减1次,到hi;i递增至hi;此时i==j。不需要exch(i,j),且要直接退出while(1)
		// (3) 一般情况	;	当i<j且需要交换二者时,执行exch(i,j)。假如某时刻,i和j之间的数都大于base,则j会移至i的位置,之后i会再递增1次,此时会出现j<i。
		if (j <= i)	break;
		else			exch(i, j);
	}
	
	return j;
}



void Quick::exch(int i, int j)
{
	int temp = v[i];
	v[i] = v[j];
	v[j] = temp;
}



void Quick::show()
{
	for (int k = 0; k < N; ++k)
	{
		cout << v[k] << " ";
	}
	cout << endl;
}
(3)注释说明

具体的实现只需要看 void Quick::sort(int lo, int hi); int Quick::position(int lo, int hi);两个函数。
sort(int lo, int hi) 递归,position()用来找到基数的合适位置。
exch(int i, int j)函数很简单,就是交换i,j处的元素。

详细说明position()函数。
i和j的起始位置需要注意一下,因为要配个后面的 ++i和 --j 的操作
在while(1)循环中,先左移j,注意的是递减是在while条件判断里的;
在基数右侧的所有数,有3种情况,见代码注释。
这里一定要想清楚 i 和 j 可能的位置关系。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值