/*
快速排序:(分治思想: 分、治、合)
不同版本:(效率越来越高)
1)、轴值取中间元素,分割时从序列的左端l,右端r向序列中间扫描。交换逆置元素,直到l、r相交。
2)、轴值取中间元素,分割时从序列的左右两端交替检查空闲位置,将逆置元素移动到空闲位置上,
直到l、r相交,最后将轴值放到空闲位置。
3)、当快速排序的子数组小于某个长度n时,不必继续递归。最后对整个数组进行一次插入排序。n=28、9、16等值。
4)、随机化的快速排序,轴值取随机值。
5)、随机找到3个元素,取中间值作为轴值。
*/
#include <iostream>
#include <time.h>
using namespace std;
#define N 16
void PrintArr(int *pnArr, int nLen)
{
int i;
for (i = 0; i < nLen; i++)
{
cout<<pnArr[i]<<" ";
}
cout<<endl;
}
int SelectPivot(int nLeft, int nRight)
{
return (nLeft + nRight) / 2;
}
int RandomSelectPivot(int nLeft, int nRight)
{
return rand()%(nRight - nLeft + 1) + nLeft;
}
int MidValue(int *pnArr, int nPos1, int nPos2, int nPos3)
{
if (pnArr[nPos1] >= pnArr[nPos2] && pnArr[nPos1] <= pnArr[nPos3] ||
pnArr[nPos1] >= pnArr[nPos3] && pnArr[nPos1] <= pnArr[nPos2])
{
return nPos1;
}
if (pnArr[nPos2] >= pnArr[nPos1] && pnArr[nPos2] <= pnArr[nPos3] ||
pnArr[nPos2] >= pnArr[nPos3] && pnArr[nPos2] <= pnArr[nPos1])
{
return nPos2;
}
if (pnArr[nPos3] >= pnArr[nPos1] && pnArr[nPos3] <= pnArr[nPos2] ||
pnArr[nPos3] >= pnArr[nPos2] && pnArr[nPos3] <= pnArr[nPos1])
{
return nPos3;
}
return 0;
}
int Random3SelectPivot(int *pnArr, int nLeft, int nRight)
{
srand(time(NULL));
int nPos1 = rand()%(nRight - nLeft + 1) + nLeft;
int nPos2 = rand()%(nRight - nLeft + 1) + nLeft;
int nPos3 = rand()%(nRight - nLeft + 1) + nLeft;
return MidValue(pnArr, nPos1, nPos2, nPos3);
}
//1、轴值取中间元素,分割时从序列的左端l,右端r向序列中间扫描。交换逆置元素,直到l、r相交。
int Partition1(int *pnArr, int nLeft, int nRight)
{
int nLPos = nLeft;
int nRPos = nRight;
int nPivotValue = pnArr[nRight]; //将轴值存放在临时变量中
while (1)
{
while (pnArr[nLPos] <= nPivotValue && nLPos < nRPos)
{
nLPos++;
}
while (pnArr[nRPos] >= nPivotValue && nLPos < nRPos)
{
nRPos--;
}
if (nLPos >= nRPos)
{
break;
}
swap(pnArr[nLPos], pnArr[nRPos]);
}
swap(pnArr[nRight], pnArr[nLPos]);
return nLPos;
}
//从小到大排序
void QuickSort1(int *pnArr, int nLeft, int nRight)
{
if (nLeft < nRight)
{
int nPivotPos = Random3SelectPivot(pnArr, nLeft, nRight);
swap(pnArr[nPivotPos], pnArr[nRight]);
nPivotPos = Partition1(pnArr, nLeft, nRight);
QuickSort1(pnArr, nLeft, nPivotPos - 1);
QuickSort1(pnArr, nPivotPos + 1, nRight);
}
}
//2、轴值取中间元素,分割时从序列的左右两端交替检查空闲位置,将逆置元素移动到空闲位置上,
// 直到l、r相交,最后将轴值放到空闲位置。
int Partition2(int *pnArr, int nLeft, int nRight)
{
int nLPos = nLeft;
int nRPos = nRight;
int nPivotValue = pnArr[nRight]; //将轴值存放在临时变量中
while (nLPos != nRPos)
{
while (pnArr[nLPos] <= nPivotValue && nLPos < nRPos)
{
nLPos++;
}
if (nLPos < nRPos)
{
pnArr[nRPos] = pnArr[nLPos];
nRPos--;
}
while (pnArr[nRPos] >= nPivotValue && nLPos < nRPos)
{
nRPos--;
}
if (nLPos < nRPos)
{
pnArr[nLPos] = pnArr[nRPos];
nLPos++;
}
}
pnArr[nLPos] = nPivotValue;
return nLPos;
}
//从小到大排序
void QuickSort2(int *pnArr, int nLeft, int nRight)
{
if (nLeft < nRight)
{
int nPivotPos = SelectPivot(nLeft, nRight);
swap(pnArr[nPivotPos], pnArr[nRight]);
nPivotPos = Partition2(pnArr, nLeft, nRight);
QuickSort2(pnArr, nLeft, nPivotPos - 1);
QuickSort2(pnArr, nPivotPos + 1, nRight);
}
}
int Partition3(int *pnArr, int nLeft, int nRight)
{
int nLPos = nLeft;
int nRPos = nRight;
int nPivotValue = pnArr[nRight]; //将轴值存放在临时变量中
while (nLPos != nRPos)
{
while (pnArr[nLPos] <= nPivotValue && nLPos < nRPos)
{
nLPos++;
}
if (nLPos < nRPos)
{
pnArr[nRPos] = pnArr[nLPos];
nRPos--;
}
while (pnArr[nRPos] >= nPivotValue && nLPos < nRPos)
{
nRPos--;
}
if (nLPos < nRPos)
{
pnArr[nLPos] = pnArr[nRPos];
nLPos++;
}
}
pnArr[nLPos] = nPivotValue;
return nLPos;
}
void InsertSort(int *pnArr, int nLen)
{
int i, j;
for (i = 1; i < nLen; i++)
{
int nTmp = pnArr[i];
for (j = i; j > 0 && pnArr[j - 1] > nTmp; j--)
{
pnArr[j] = pnArr[j-1];
}
pnArr[j] = nTmp;
}
}
//当快速排序的子数组小于某个长度n时,不必继续递归。最后对整个数组进行一次插入排序。n=28、9、16等值。
void QuickSort3(int *pnArr, int nLeft, int nRight)
{
if (nRight - nLeft + 1> 9)
{
int nPivotPos = SelectPivot(nLeft, nRight);
swap(pnArr[nPivotPos], pnArr[nRight]);
nPivotPos = Partition3(pnArr, nLeft, nRight);
QuickSort3(pnArr, nLeft, nPivotPos - 1);
QuickSort3(pnArr, nPivotPos + 1, nRight);
}
else
{
InsertSort(pnArr, nRight - nLeft + 1);
}
}
int main()
{
int nArr[N] = {0};
int i;
srand(time(NULL));
for (i = 0; i < N; i++)
{
nArr[i] = rand() % 100; //rand(nMax - nMin + 1) + nMin ----> [nMin, nMax]
}
PrintArr(nArr, N);
QuickSort1(nArr, 0, N - 1);
PrintArr(nArr, N);
return 0;
}
快速排序
最新推荐文章于 2022-02-13 21:46:32 发布