排序算法:堆排,快排的实现(快排的三种实现方法以及快排的优化)
Posted It‘s so simple
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法:堆排,快排的实现(快排的三种实现方法以及快排的优化)相关的知识,希望对你有一定的参考价值。
1. 堆排
升序建大堆,逆序建小堆,先建堆,堆建好之后,将堆中最后一个元素和第一元素互换,然后执行向下调整算法进行调堆,最终实现相应的顺序。
void AdjustDown(vector<int>& iv, int pos,int n)
{
int parent = pos;
int child = pos * 2 + 1;
while (child < n)
{
if (child + 1 < n && iv[child] < iv[child + 1])
++child;
if (iv[parent] < iv[child])
{
swap(iv[parent], iv[child]);
parent = child;
child = parent * 2 + 1;
}
else
break;
}
}
void HeapSort(vector<int>& iv)
{
for (int i = (iv.size()-1) >> 1 ; i >= 0; --i)
{
AdjustDown(iv, i,iv.size());
}
int end = iv.size() - 1;
while (end >= 0)
{
swap(iv[end], iv[0]);
AdjustDown(iv, 0,end);
--end;
}
}
int main()
{
vector<int> iv = { 2,5,6,7,8,9 };
HeapSort(iv);
for (const auto& e : iv)
{
cout << e << " ";
}
cout << endl;
return 0;
}
2. 快排
2.1 双指针法
void _QuickSort(vector<int>& iv, int left, int right)
{
if (left >= right)
return;
int begin = left;
int end = right;
int key = left;
while (begin < end)
{
while (begin < end && iv[end] >= iv[key])
--end;
while (begin < end && iv[begin] <= iv[key])
++begin;
swap(iv[end], iv[begin]);
}
swap(iv[key], iv[begin]);
key = begin;
_QuickSort(iv, left, key - 1);
_QuickSort(iv, key + 1,right);
}
void QuickSort(vector<int>& iv)
{
_QuickSort(iv, 0, iv.size()-1);
}
2.2 挖坑法
void _QuickSort(vector<int>& iv, int left, int right)
{
if (left >= right)
return;
int begin = left;
int hole = iv[left];
int end = right;
while (begin < end)
{
while (begin < end && iv[end] >= hole)
--end;
iv[begin] = iv[end];
while (begin < end && iv[begin] <= hole)
++begin;
iv[end] = iv[begin];
}
iv[begin] = hole;
int key = begin;
_QuickSort(iv, left, key - 1);
_QuickSort(iv, key + 1, right);
}
2.3 前后指针法
void _QuickSort(vector<int>& iv, int left, int right)
{
if (left >= right)
return;
int next = left;
int key = right;
int prev = left - 1;
while (next != key)
{
if (iv[next] < iv[key] && ++prev != next)
{
swap(iv[next], iv[prev]);
}
++next;
}
swap(iv[key], iv[++prev]);
key = prev;
_QuickSort(iv, left, key - 1);
_QuickSort(iv, key + 1, right);
}
2.4 非递归
void _QuickSort(vector<int>& iv, int left, int right)
{
stack<int> st;
st.push(left);
st.push(right);
while (!st.empty())
{
int r = st.top();
st.pop();
int l = st.top();
st.pop();
int end = r;
int begin = l;
int hole = iv[begin];
while (begin < end)
{
while (begin < end && iv[end] >= hole)
--end;
iv[begin] = iv[end];
while (begin < end && iv[begin] <= hole)
++begin;
iv[end] = iv[begin];
}
iv[begin] = hole;
int key = begin;
if (key - 1 > l)
{
st.push(l);
st.push(key - 1);
}
if (key + 1 < r)
{
st.push(key + 1);
st.push(r);
}
}
}
2.5 快排的优化(三数取中+小区间优化)
三数取中
int getMidIndex(vector<int>& a,int left, int right)
{
//首先求出mid的值
int mid = (left + right) >> 1;
//当left < mid时
if(a[left] < a[mid])
{
//当mid < right 时,返回mid的值(位于中间)
if(a[mid] < a[right])
{
return mid;
}
else if(a[right] < a[left])
{
return left;
}
else
{
return right;
}
}
else //left >= mid
{
if(a[mid] > a[right])
{
return mid;
}
else if(a[left] < a[right])
{
return left;
}
else
{
return right;
}
}
}
小区间优化
//快排优化----最小区间优化
//当[left,right]的范围很小时,即数据量很小时,
//就直接使用插入排序,减少递归的次数(即相当于减少叶子节点的递归数目)
void InsertSort(vector<int>& iv)
{
for (int i = 0; i < iv.size() - 1; ++i)
{
int end = i;
int tmp = iv[end + 1];
while (end >= 0)
{
if (iv[end] > tmp)
{
iv[end + 1] = iv[end];
--end;
}
else
break;
}
iv[end + 1] = tmp;
}
}
以上是关于排序算法:堆排,快排的实现(快排的三种实现方法以及快排的优化)的主要内容,如果未能解决你的问题,请参考以下文章
排序算法:堆排,快排的实现(快排的三种实现方法以及快排的优化)