快速排序

  去年大一下学数据结构的时候,学到了快速排序,记得当时怎么都不理解~!尤其不理解递归的实现。

  今天复习算法的时候发现并不是当时想的那么难,于是就代码实现了一下!我们都知道快排的效率高低取决于基准元素(这个可能不同的人叫法不一样,就是交换轴,我想你懂的,O(∩_∩)O~)的选择,一般我们选取第一个元素(或某一个),但是这样选取可能会导致快排的最低效率。还可以随机选取一个元素作为基准元素。

代码:

 

/* 主题:快速排序
* 作者:chinazhangjie
* 邮箱:chinajiezhang@gmail.com
* 开发语言: C++
* 开发环境: Virsual Studio 2005
* 时间: 2010.12.09
*/
#include
<iostream>
#include
<vector>
#include
<algorithm>
#include
<iterator>
#include
<ctime>
#include
<windows.h>

using namespace std;
template
<class T>
class Sort
{
public:
Sort (
const vector<T>& vsortData, bool bsortMode)
: m_vsortData(vsortData), m_bsortMode(bsortMode)
{}
virtual void QSort()
{
__QSort (
0, m_vsortData.size() - 1) ;
}
// display all element
void display () const
{
for (size_t i = 0; i < m_vsortData.size() / 10; ++ i)
{
copy (m_vsortData.begin()
+ 10 * i,
m_vsortData.begin()
+ 10 * i + 10,
ostream_iterator
<int>(cout," "));
cout
<< endl ;
}
}
protected:
bool __compare (const T& rth, const T& lth)
{
return m_bsortMode ? (rth < lth) : (rth > lth) ;
}
virtual void __QSort (int istart, int iend)
{
if (istart < iend)
{
int isegLocation = __partition (istart, iend) ;
__QSort (istart, isegLocation
- 1) ;
__QSort (isegLocation
+ 1, iend) ;
}
}
virtual int __partition(int istart, int iend)
{
int iinc = istart ;
int idec = iend ;

T midData
= m_vsortData[iinc] ;
while (true)
{
while (__compare (m_vsortData[iinc], midData) && iinc <= iend)
{
++ iinc ;
}
while (__compare (midData, m_vsortData[idec]) && idec >= istart)
{
-- idec ;
}
if (iinc >= idec)
break ;
swap (m_vsortData[iinc], m_vsortData[idec]) ;
Sleep (
100) ; // 增大交换的代价
}
swap (m_vsortData[iinc], m_vsortData[idec]) ;
return idec ;
}
virtual int __getPivot(int istart, int iend) = 0 ;
protected:
vector
<T> m_vsortData ;
// true:从小到大,false: 从大到小
bool m_bsortMode ;
} ;

template
<class T>
class QuickSort : public Sort<T>
{
public:
QuickSort (
const vector<T>& vsortData, bool bsortMode)
: Sort (vsortData, bsortMode)
{}
protected:
virtual int __getPivot(int istart, int iend)
{
return istart ;
}
} ;
template
<class T>
class RandomQuickSort : public Sort<T>
{
public:
RandomQuickSort (
const vector<T>& vsortData, bool bsortMode)
: Sort (vsortData, bsortMode)
{}
protected:
virtual int __getPivot(int istart, int iend)
{
srand (time(NULL)) ;
return istart + rand () % (iend - istart) ;
}
} ;

int main ()
{
const int size = 100;
vector
<int> sortdata (size) ;
for (int i = 0; i < size; ++ i)
{
sortdata[i]
= i ;
}
random_shuffle (sortdata.begin(), sortdata.end()) ;

QuickSort
<int> qs (sortdata, false) ;
SYSTEMTIME sys1;
SYSTEMTIME sys2;

GetLocalTime(
&sys1) ;
qs.QSort () ;
GetLocalTime(
&sys2) ;

printf (
"%d, %d\n",
(sys2.wSecond
- sys1.wSecond), (sys2.wMilliseconds - sys1.wMilliseconds));

random_shuffle (sortdata.begin(), sortdata.end()) ;
// qs.display () ;
RandomQuickSort<int> rqs (sortdata, true);
GetLocalTime(
&sys1) ;
rqs.QSort () ;
GetLocalTime(
&sys2) ;

printf (
"%d, %d\n",
(sys2.wSecond
- sys1.wSecond), (sys2.wMilliseconds - sys1.wMilliseconds));

return 0 ;
}

 

理论上来说,随机取值回比直接选取效率要高一下,但是一开始测试的结果确实相反的,无论我采用多大的数组,直接选取效率要高于随机取值效率高。

后来我仔细想了一下,在我的程序中交换消耗的时间可能要比获得随机数的时间要短的多,所以才会有这种效果。也就是说有点本末倒置了,事实上交换的时间应该远大于获得随机数的时间。为了验证我的结论我在交换后加了一条语句sleep,也就是增加交换消耗的时间。运行后,果然如此。所以和我们想的一样,随机选取要比直接选取效率要高。我一直觉得会有更好的算法来选择基准元素,比如去中位数之类的,但是局限性有太强,只有具体问题具体分析了。

ok,表述完毕,吃饭去了!

 

posted @ 2010-12-09 17:33 独酌逸醉 阅读(...) 评论(...) 编辑 收藏