快速排序的基本思想:任取待排序元素序列中的某个元素(例如取第一个元素)作为基准,按照该元素的排序码大小,将整个元素序列划分为左右两个子序列;左侧子序列中元素的排序码都小于基准元素的排序码,右侧子序列中的元素的排序码都大于基准元素的排序码。然后在左右序列中重复这种操作。
void Swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int Partition(int V[], int low, int high)
{
int privotpos = low;
int privot = V[low];
for(int i = low+1; i < high+1; ++i)
{
if(V[i] < privot)
{
privotpos++;
if(privotpos != i)
{
Swap(V[privotpos],V[i]);
}
}
}
V[low] = V[privotpos];
V[privotpos] = privot;
return privotpos;
}
void QuickSort(int V[], const int left, const int right)
{
if(left < right)
{
int privotpos = Partition(V, left, right);
QuickSort(V,left, privotpos-1);
QuickSort(V,privotpos+1, right);
}
}
快速排序的改进算法:当序列长度M取值为5~25时,采用直接插入排序比全部使用快速排序快10%
#define M 5
void QuickSort_insertSort(int V[], const int left, const int right)
{
if(right-left <= M)
{
InsertSort(V, left, right);
}
if(left < right)
{
int privotpos = Partition(V, left, right);
QuickSort(V,left, privotpos-1);
QuickSort(V,privotpos+1, right);
}
}
void QuickSort(int V[], const int left, const int right)
{
if(left < right)
{
int privotpos = Partition(V, left, right);
QuickSort(V,left, privotpos-1);
QuickSort(V,privotpos+1, right);
}
}
void InsertSort(int V[], const int left, const int right)
{
int i, j;
for(i = left+1; i < right+1; ++i)
{
if(V[i] < V[i-1])
{
int tmp = V[i];
j = i-1;
do
{
V[j+1] = V[j];
j--;
}while(j >= left && tmp < V[j]);
//向后移位
V[j+1] = tmp;
}
}
}
快速—直接插入混合排序算法
void NewQuickSort(int V[], const int left, const int right)
{
if(right-left <= M)
{
return;
}
if(left < right)
{
int privotpos = Partition(V, left, right);
NewQuickSort(V,left, privotpos-1);
NewQuickSort(V,privotpos+1, right);
}
}
void HybirdSort(int V[], const int left, const int right)
{
NewQuickSort(V, left, right);
InsertSort(V, left, right);
}
三者中取中算法来实现快速排序基准位
int median3(int V[], int left, int right)
{
int mid = (left+right)/2;
int k = left;
if(V[mid] < V[k])
{
k = mid;
}
if(V[right] < V[k])
{
k = right;//k指向三者中最小值
}
if(k != left)
{
Swap(V[k], V[left]);
}
if(mid != right && V[mid] < V[right])
{
Swap(V[mid], V[right]);
}
return V[right];
}
//一趟划分算法的实现
int Partition_3(int V[], int left, int right)
{
int i = left, j = right-1;
if(left < right)
{
int privot = median3(V, left, right);
while(1)
{
while(i<j && V[i] < privot)
//正向,小于privot的留在左侧,一旦大于等于privot停步
{
i++;
}
while(i<j && privot < V[j])
//反向,大于privot的留在右侧,一旦小于等于privot停步
{
j--;
}
if(i < j)
//比privot小的交换到左侧,比privot大的交换到右侧
{
Swap(V[i], V[j]);
i++;
j--;
}
else
//i=j表明一趟检测完成,终止循环
{
break;
}
}
if(V[i] > privot)
//privot移到它排序后应该在的位置
{
V[right] = V[i];
V[i] = privot;
}
}
return i;
}
void NewQuickSort_3(int V[], const int left, const int right)
//三者中取中值放在最右端
{
if(right-left <= M)
{
return;
}
if(left < right)
{
int privotpos = Partition_3(V, left, right);
QuickSort(V,left, privotpos-1);
QuickSort(V,privotpos+1, right);
}
}
void HybirdSort_3(int V[], const int left, const int right)
{
NewQuickSort(V, left, right);
InsertSort(V, left, right);
}
三路划分的快速排序算法
void QuickSortNew(int V[], int left, int right)
{
int i, j, k, p, q;
int privot = V[right];
if(right <= left)
{
return;
}
i = left-1;
j = right;
p = left-1;
q = right;
while(1)
{
while(V[++i] < privot)
{
if(i == j)
{
break;
}
}
while(privot < V[--j])
{
if(j == i)
{
break;
}
}
if(i >= j)
{
break;
}
Swap(V[i], V[j]);
if(V[i] == privot)
{
p++;
Swap(V[p], V[i]);
}
if(privot == V[j])
{
q--;
Swap(V[q], V[j]);
}
}
if(V[i] > V[right])
{
Swap(V[i], V[right]);
k = right-1;
}
else
{
k = right;
}
j--;
i++;
while(k >= q)
{
Swap(V[k], V[i]);
k--;
i++;
}
for(k = left; k < p+1; k++, j--)
{
Swap(V[k], V[j]);
}
QuickSortNew(V, left, j);
QuickSortNew(V, i, right);
}