快速排序
去年大一下学数据结构的时候,学到了快速排序,记得当时怎么都不理解~!尤其不理解递归的实现。
今天复习算法的时候发现并不是当时想的那么难,于是就代码实现了一下!我们都知道快排的效率高低取决于基准元素(这个可能不同的人叫法不一样,就是交换轴,我想你懂的,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,表述完毕,吃饭去了!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器