#include <iostream>
#include<algorithm>
using namespace std;
int RoundPartition(int R[], int s, int e); //对R[s..e]进行一次随机划分,返回枢轴下标
void RoundQuickSort(int R[], int s, int e); //对R[s..e]进行随机快速排序
int QuickSelect(int R[], int s, int e, int k); //返回R[s..e]中第k小的元素,k≥1
void Output(int R[], int s, int e); //遍历输出R[s..e]
int A[] = { 52, 49, 14, 36, 23, 61, 58, 80, 75, 97 };//待排序实例数据(较好情况)
//int A[] = { 14, 23, 36, 49, 52, 58, 61, 75, 80, 97 };//待排序实例数据(较差情况)
int n; //实例数据的数量
int main()
{
n = sizeof(A) / sizeof(A[0]);
cout << "序列:"; Output(A, 0, n - 1); cout <<"\n\n";
RoundQuickSort(A, 0, n - 1); cout << endl; //对R[0..n-1]进行随机快速排序
cout << "快速排序后:"; Output(A, 0, n - 1); cout << endl;
//srand(time(0));
//int k = rand()%n+1;
//cout << "第" << k << "小的元素是 " << QuickSelect(A, 0, n-1, k) << endl;
system("pause");
return 0;
}
//对R[s..e]进行一次划分,返回枢轴下标
int RoundPartition(int R[], int s, int e)
{
static int count = 1;
int low = s, high = e;
/*补充代码①:划分区间内随机取一个元素为枢轴,将其与区间内的第一个元素互换
*
*
*/
int randomIndex = s + rand() % (e - s + 1); // 生成[s,e]范围内的随机索引
swap(R[s], R[randomIndex]); // 随机元素与第一个元素交换
int x = R[s]; //序列第一个元素作为枢轴x
cout << "第" << count << "趟,";
cout << "划分区间[" << low << "," << high << "]," << "枢轴元素" << R[s] << ":";
Output(A, s, e); cout << endl;
while (low < high)
{
while (low < high && R[high] >= x) {
//从右到左查找比枢轴小的元素
high--;
}
R[low] = R[high]; //将小数放在左侧小数序列中
while (low < high && R[low] < x) {
//从左到右查找比枢轴大或相等的元素
low++;
}
R[high] = R[low]; //将大数放在右侧大数序列中
} //循环结束时low、high重合
R[low] = x; //确定枢轴的最终存放位置
cout << "\t\t\t划分结果:"; Output(A, s, e); cout << "枢轴下标:" << low << endl;
count++;
return low;//返回枢轴归位的位置
}
//对R[s..e]进行快速排序
void RoundQuickSort(int R[], int s, int e)
{
if (s < e) //区间内至少有2个元素
{
/*补充代码②:随机划分一次,得到枢轴归位位置*/
/*补充代码③:如果枢轴归位位置的左侧区间至少有2个元素,则对左侧小数序列进行递归划分*/
/*补充代码④:如果枢轴归位位置的右侧区间至少有2个元素,则对右侧大数序列进行递归划分*/
/*补充代码②:随机划分一次,得到枢轴归位位置*/
int pos = RoundPartition(R, s, e);
/*补充代码③:如果枢轴归位位置的左侧区间至少有2个元素,则对左侧小数序列进行递归划分*/
if (s < pos - 1) {
RoundQuickSort(R, s, pos - 1);
}
/*补充代码④:如果枢轴归位位置的右侧区间至少有2个元素,则对右侧大数序列进行递归划分*/
if (pos + 1 < e) {
RoundQuickSort(R, pos + 1, e);
}
}
}
//返回R[s..e]中第k小的元素,k≥1
int QuickSelect(int R[], int s, int e, int k)
{
if (s < e) //区间内至少有2个元素
{
/*补充代码②:随机划分一次,得到枢轴归位位置*/
/*补充代码⑤:如果枢轴位置就是目标位置k,则返回枢轴元素*/
/*补充代码⑥:如果目标位置在枢轴左侧,下一次在小数序列递归查找*/
/*补充代码⑦:如果目标位置在枢轴右侧,下一次在大数序列递归查找*/
/*补充代码②:随机划分一次,得到枢轴归位位置*/
int pos = RoundPartition(R, s, e);
int relativePos = pos - s + 1; // 枢轴在区间中的相对位置
/*补充代码⑤:如果枢轴位置就是目标位置k,则返回枢轴元素*/
if (k == relativePos) {
return R[pos];
}
/*补充代码⑥:如果目标位置在枢轴左侧,下一次在小数序列递归查找*/
else if (k < relativePos) {
return QuickSelect(R, s, pos - 1, k);
}
/*补充代码⑦:如果目标位置在枢轴右侧,下一次在大数序列递归查找*/
else {
return QuickSelect(R, pos + 1, e, k - relativePos);
}
}
/*补充代码⑧:如果区间内只有一个元素且位于目标位置k,返回其值*/
return R[s];
}
//遍历输出R[s..e]
void Output(int R[], int s, int e)
{
for (int i = 0; i < s; i++)
printf(" ,");
for (int i = s; i <= e; i++)
printf("%4d,", R[i]);
for (int i = e + 1; i < n; i++)
printf(" ,");
cout << "\b ";
}利用第这个代码的算法实现随机快速排序
最新发布