竞赛训练5 排序:Stable Sort

竞赛训练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;
}

总结:在对不同排序算法了解并能熟练写出后,还需要对其一些特性了解,这样做题可以节省很多时间,有时候也会减少时间复杂度。

std::stable_sort和std::sort是C++标准库中的两个排序算法,它们在排序元素时有一些区别。 1. std::sort是一不稳定的排序算法,而std::stable_sort是一稳定的排序算法。稳定排序算法意味着如果两个元素的值相等,它们在排序后的结果中的相对顺序将保持不变。而不稳定排序算法则没有这个保证。 2. std::sort的平均时间复杂度为O(nlogn),std::stable_sort的平均时间复杂度为O(nlog^2n)。这是因为std::stable_sort需要保持相等元素的相对顺序,所以在排序过程中需要更多的操作。 3. std::sort使用的是快速排序算法或者堆排序算法,而std::stable_sort使用的是归并排序算法。快速排序和堆排序是原地排序算法,它们不需要额外的内存空间。而归并排序需要额外的内存空间来存储临时结果。 下面是一个使用std::sort和std::stable_sort的示例: ```cpp #include <iostream> #include <algorithm> #include <vector> int main() { std::vector<int> nums = {5, 2, 8, 3, 1, 4}; // 使用std::sort进行排序 std::sort(nums.begin(), nums.end()); std::cout << "使用std::sort排序后的结果:"; for (int num : nums) { std::cout << num << " "; } std::cout << std::endl; // 使用std::stable_sort进行排序 std::stable_sort(nums.begin(), nums.end()); std::cout << "使用std::stable_sort排序后的结果:"; for (int num : nums) { std::cout << num << " "; } std::cout << std::endl; return 0; } ``` 输出结果: 使用std::sort排序后的结果:1 2 3 4 5 8 使用std::stable_sort排序后的结果:1 2 3 4 5 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值