题目信息
要求根据给定输入,按照课堂给定的快速排序算法进行排序,输出排序结果和median3的返回值。
注
1 cutoff值为5,不足cutoff使用插入排序。
2 输入、输出格式参见测试用例。
测试样例
测试样例1
41
17
34
0
19
#
After Sorting:
0 17 19 34 41
Median3 Value:
none
测试样例2
61
59
82
-10
31
-2
-3
10
2
108
12
80
-21
127
12
#
After Sorting:
-21 -10 -3 -2 2 10 12 12 31 59 61 80 82 108 127
Median3 Value:
12 -3 61
解答
#include<iostream>
#include<algorithm>
using namespace std;
int sz[100], median[100];
int mNum = 0;
int Median3(int lt, int rt)
{
//三平均划分法
int Middle = (lt + rt) / 2;
if (sz[lt] > sz[Middle])
{
//满足中间的要比左边的大
swap(sz[lt], sz[Middle]);
}
if (sz[lt] > sz[rt])
{
//满足右边的要比左边的大
swap(sz[lt], sz[rt]);
}
if (sz[Middle] > sz[rt])
{
//满足右边的比中间的大
swap(sz[Middle], sz[rt]);
}
swap(sz[Middle], sz[rt - 1]);//将中间的放置在倒数第二个的位置
median[mNum++] = sz[rt - 1];//将中间值存在median数组中
return sz[rt - 1];
}//实际上是我们抓取了三个数,第一个中间的最后一个按照大小排序后,取出中间的那个
void InsertSort(int lt, int rt)
{
for (int i = lt + 1; i <= rt; i++)
{
int temp = sz[i];
if (sz[i] < sz[i - 1])
{
int j = lt;
while (sz[j] < temp)
{
j++;
}
for (int k = i; k > j; k--)
{
//后移
sz[k] = sz[k - 1];
}
sz[j] = temp;
}
}
}
void QuickSort(int lt, int rt)
{
if (rt - lt < 5)
{
//个数小于5的时候使用插入排序的方法
InsertSort(lt, rt);
}
else if (lt < rt)
{
int pivot = Median3(lt, rt);//得到了中间的那个数
int L = lt, R = rt - 1; //从左到右的扫描从第一个元素开始,从右到左的扫描从倒数第二个元素开始
while (L < R)
{
//找到左边的比中数大,右边的比中数小,然后交换之
while (L < R && sz[++L] < pivot);
while (L < R && sz[--R] > pivot);
swap(sz[L], sz[R]);
}
swap(sz[L], sz[rt - 1]);//将中数放置在中间的位置
int Middle = L; // 中轴
if (Middle)
{
//递归下去
QuickSort(lt, Middle - 1);
QuickSort(Middle + 1, rt);
}
}
}
int main()
{
//freopen("/Users/zhj/Downloads/test.txt", "r", stdin);
string s;
int len = 0;
while (true)
{
cin >> s;
if (s[0] == '#')
{
break;
}
sz[len] = atoi(s.c_str());
++len;
}
QuickSort(0, len - 1);
cout << "After Sorting:" << endl;
for (int i = 0; i < len; ++i)
{
cout << sz[i] << " ";
}
cout << endl;
cout << "Median3 Value:" << endl;
if (len > 5)
{
for (int i = 0; i < mNum; ++i)
{
cout << median[i] << " ";
}
}
else
{
cout << "none";
}
cout << endl;
}
想法
- 本题考察的就是快速排序的三平均划分法,实现一种分治的思想。
- 首先选出三个值,第一个数,中间的数,最后一个数,将这三个数按大小排好序,
A < B < C
。 - 对剩余的数字,将小于B的数放置在左边,大于B的数放置在右边。
- 对左右两堆数实现递归,不断循环上述过程。
- 如果剩余的数小于等于5个的时候就是用插入排序的方式。