温故而知新【快速排序】

4 篇文章 0 订阅
<pre name="code" class="cpp">#if !defined(_SORT_INCLUDED_H)
#define _SORT_INCLUDED_H

#include <iostream>
/*
分别使用递归和循环来实现快速排序,虽然已经写了4年多代码了
但是发现一次性写的完整无误还真是...呵呵
author:davidsu33
datetime:2015-3-1
*/

/*
快速排序,使用递归
*/

template<class Iterator>
void swap_value(Iterator l, Iterator r)
{
	Iterator::value_type aValue;
	aValue = *l;
	*l = *r;
	*r = aValue;
}

template<class Iterator>
void trace_vector(Iterator begin, Iterator end)
{
	for(; begin <= end; ++begin)
	{
		std::cout<<*begin << ",";
	}

	std::cout<<std::endl;
}

template<class Iterator, class Compare>
void quick_sort(Iterator begin, Iterator end)
{
	typedef Iterator::distance_type DistanceType;
	typedef Iterator::value_type ValueType;
	Compare comp;

	if (end - begin <= 1)
	{
		return;
	}

	Iterator l = begin;
	Iterator r = end - 1;

	DistanceType midPos = (r - l) / 2;
	Iterator mid = begin + midPos;
	ValueType value = *mid;//确定这个数值的位置

	//std::cout<< "value="<<value<<std::endl;
	//查找value排序后的位置,即左侧都小于value,右侧都大于value
	while(l < r)
	{
		for (; l < mid; ++l)
		{
			//之前我是这么写的
			//if(!comp(*l, value)会导致等于的时候也认为需要交换位置,
			//有可能会让程序陷入死循环,因为comp里面,我只是返回
			//了大小关系没有考虑=的情况,两种该法,一个修改comp的
			//判断,加上等于,等于返回true,
			//另外一种就是这样,反过来判断,我认为这样更加符合操作习惯
			if (comp(value,*l))
			{
				*mid = *l;
				mid = l;
				break;
			}
		}

		for (; mid < r; --r)
		{
			if (comp( *r,value))
			{
				*mid = *r;
				mid = r;
				break;
			}
		}
	}
	
	*mid = value;
	//std::cout<<"mid pos:"<<mid - begin << std::endl;

	//value的位置已经确定,不再参与排序
	quick_sort<Iterator, Compare>(begin, mid);
	quick_sort<Iterator, Compare>(mid+1, end);
}

/*
不使用递归来实现
*/
#include <queue>

//编码时少些了一个t的引用符号,导致排序错误
//编写算法的时候要特别注意啊

template<class Iterator>
void find_self_pos(Iterator l, Iterator r, Iterator &t)
{
	Iterator::value_type key = *t;
	while (l < r)
	{
		for (; l < t; ++l)
		{
			if (*l > key)
			{
				*t = *l;
				t = l;
				break;
			}
		}

		for (; t < r; --r)
		{
			if (*r < key)
			{
				*t = *r;
				t = r;
				break;
			}
		}
	}

	*t = key;
}

template<class Iterator>
void quick_sort_for(Iterator begin, Iterator end)
{
	if (end - begin <= 1)
	{
		return;
	}

	Iterator l = begin, r = end - 1;
	
	typedef std::pair<Iterator,Iterator> IntPair;
	std::queue<IntPair> mids;
	mids.push(IntPair(l, r));

	while (!mids.empty())
	{
		IntPair f = mids.front();
		//m可以是迭代范围中的任何一个值,这里默认取的是中间值
		Iterator m = f.first + (f.second - f.first)/2;
		find_self_pos(f.first, f.second, m);
		
		mids.pop();
		
		if(m - f.first >= 1)
			mids.push(IntPair(f.first, m-1));
		if(f.second -m >=1)
			mids.push(IntPair(m+1, f.second));
	}
}

#endif



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值