竞赛训练5 排序:Stable Sort
题目来源:《挑战程序设计竞赛》
题目:我们使用的扑克牌包含S、H、C、D的4种花色(Suit)以及1,2,……,9的9个数字(Value),共计36张。例如红桃8记为H8,方块1记为D1。请用冒泡排序和选择排序对输入的N张扑克牌进行以数字为基准的升序排列。并判断两种算法是否有稳定的输出。
输入:在第一行输入扑克牌张数N。在第二行输入N张扑克牌的数据,每张牌由代表花色和数字的2个字符组成,相邻扑克牌之间用一个空格隔开。
输出:输出总计2行。第一行输出冒泡排序后的扑克牌。相邻扑克牌用一个空格隔开。第二行输出该输出是否稳定。第三行输出选择排序后的扑克牌。相邻扑克牌用一个空格隔开。第四行输出该输出是否稳定。
限制:1≤N≤36
输入示例
5
H4 C9 S4 D2 C3
输出示例
D2 C3 H4 S4 C9
Stable
D2 C3 S4 H4 C9
Not Stable
有一个地方需要注意的,题目其实只按照扑克牌数字大小排序,对于花色并不要求。冒泡排序和选择排序直接写,关键是对于稳定性的判断。由于题目的要求是冒泡排序和选择排序,而冒泡排序是稳定排序,所以冒泡排序直接输出“Stable”即可,而对于选择排序,只需判断排序后的花色和数字是否和冒泡排序的结果一样即可,一样则是稳定的,不一样就是不稳定的。
下面贴出我的代码:
#include<iostream>
using namespace std;
#define MAX 1000
struct Card
{
char suit;
int value;
};
//冒泡排序
void BubbleSort(struct Card a[],int n)
{
int flag,i,j;
i=0;
flag=1;
while(flag)
{
flag=0;
for(j=n-1;j>=i+1;j--)
{
if(a[j].value<a[j-1].value)
{
swap(a[j],a[j-1]);
flag=1;
}
}
i++;
}
}
//选择排序
void SelectionSort(struct Card a[],int n)
{
int i,j,minj;
for(i=0;i<n-1;++i)
{
minj=i;
for(j=i+1;j<n;++j)
{
if(a[j].value<a[minj].value)
{
minj=j;
}
}
swap(a[i],a[minj]);
}
}
//判断稳定性
bool JudgeStable(struct Card a[],struct Card b[],int n)
{
for(int i=0;i<n;++i)
{
if(a[i].value!=b[i].value||a[i].suit!=b[i].suit)
{
return false;
}
}
return true;
}
int main()
{
int n;
struct Card a[MAX],b[MAX];
cin>>n;
for(int i=0;i<n;++i)
{
cin>>a[i].suit>>a[i].value;
b[i].suit=a[i].suit;
b[i].value=a[i].value;
}
SelectionSort(b,n);
BubbleSort(a,n);
for(int i=0;i<n;++i)
{
cout<<a[i].suit<<a[i].value<<" ";
}
cout<<endl<<"Stable"<<endl;
for(int i=0;i<n;++i)
{
cout<<b[i].suit<<b[i].value<<" ";
}
if(JudgeStable(a,b,n))
{
cout<<endl<<"Stable";
}
else
{
cout<<endl<<"Not Stable";
}
return 0;
}
总结:在对不同排序算法了解并能熟练写出后,还需要对其一些特性了解,这样做题可以节省很多时间,有时候也会减少时间复杂度。