讲解
由于本题中的N值较小,因此我们在检查排序结果是否稳定时,可以用Program3.2中的这种比较笨的O(N^4)算法。
Program3.2 用笨办法判断稳定性
isStable(in,out)
for i = 0 to N-1
for j = i+1 to N-1
for a = 0 to N-1
for b = a+1 to N-1
if in[i]与in[j]的数字相等 && in[i] == out[b] && in[j] == out[a]
return false
return true
考察
本题中使用O(N^4)的算法足以满足要求,但在处理N更大的问题时,就需要多花些心思了。冒泡排序法属于稳定排序算法,因此输出永远都是"Stable"。然而,选择排序法是一种不稳定的排序算法,因此必须检查输出结果。其实,我们可以将选择排序的结果与冒泡排序的结果相比较,如此一来只用O(N)便能解决问题。
C++版本:
#include<iostream>
using namespace std;
struct Card{
char suit,value;
};
void bubble(struct Card A[],int N){
for(int i=0;i<N;i++){
for(int j=N-1;j>=i+1;j--){
if(A[j].value<A[j-1].value){
Card t=A[j];
A[j]=A[j-1];
A[j-1]=t;
}
}
}
}
void selection(struct Card A[],int N){
for(int i=0;i<N;i++){
int minj=i;
for(int j=i;j<N;j++){
if(A[j].value<A[minj].value)
minj=j;
}
Card t=A[i];
A[i]=A[minj];
A[minj]=t;
}
}
void print(struct Card A[],int N){
for(int i=0;i<N;i++){
if(i>0)
cout<<" ";
cout<<A[i].suit<<A[i].value;
}
cout<<endl;
}
//比较冒泡排序和选择排序的结果
bool isStable(struct Card C1[],struct Card C2[],int N){
for(int i=0;i<N;i++){
if(C1[i].suit!=C2[i].suit)
return false;
}
return true;
}
int main(){
Card C1[100],C2[100];
int N;
char ch;
cin>>N;
for(int i=0;i<N;i++){
cin>>C1[i].suit>>C1[i].value;
}
for(int i=0;i<N;i++)
C2[i]=C1[i];
bubble(C1,N);
selection(C2,N);
print(C1,N);
cout<<"Stable"<<endl;
print(C2,N);
if(isStable(C1,C2,N)){
cout<<"Stable"<<endl;
}else{
cout<<"Not stable"<<endl;
}
return 0;
}
JAVA版本:
import java.io.*;
import java.util.*;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
static StringBuilder out= new StringBuilder();
public static void main(String[] args) throws IOException {
int N = Integer.parseInt(br.readLine());
String A1[] = br.readLine().split(" ");
String A2[] = Arrays.copyOf(A1, N);
bubblesort(A1, N);
selectsort(A2, N);
isstable(A1, A2);
out.append(A1[0]);
for(int i=1; i<A1.length; i++) out.append(' ').append(A1[i]);
out.append('\n');
out.append("Stable\n");
out.append(A2[0]);
for(int i=1; i<A2.length; i++) out.append(' ').append(A2[i]);
out.append('\n');
out.append(isstable(A1, A2)?"Stable\n":"Not stable\n");
System.out.print(out);
}
public static void bubblesort(String[] A, int N) {
for (int i = 0; i < N-1; i++) {
for (int j = N - 1; j > i; j--) {
if (A[j].charAt(1) < A[j - 1].charAt(1)) {
String tmp = A[j];
A[j] = A[j - 1];
A[j - 1] = tmp;
}
}
}
}
public static void selectsort(String[] A, int N) {
for (int i = 0; i < N; i++) {
int min = i;
for (int j = i+1; j < N; j++) {
if (A[j].charAt(1) < A[min].charAt(1)) {
min = j;
}
}
if (i != min) {
String t = A[i];
A[i] = A[min];
A[min] = t;
}
}
}
public static boolean isstable(String[] A1, String[] A2) {
for (int i = 0; i < A1.length; i++) {
if (A1[i].charAt(0) != A2[i].charAt(0)) {
return false;
}
}
return true;
}
}
C#版本:
// Stable_Sort.cs
using System;
class Stable_Sort {
public static void Main() {
string num = Console.ReadLine();
int n = int.Parse(num);
string[] arr = new string[n];
string cards = Console.ReadLine();
arr = cards.Split();
string[] mem = new string[n];
for(int i = 0; i < n; i++) {
mem[i] = arr[i];
}
for(int j = 0; j < n; j++) {
for(int i = n - 1; i > j; i--) {
if((int)arr[i][1] < (int)arr[i - 1][1]) {
Swap(ref arr[i], ref arr[i - 1]);
}
}
}
for(int i = 0; i < n; i++) {
if(i != n - 1)
Console.Write(arr[i] + " ");
else
Console.WriteLine(arr[i]);
}
Console.WriteLine("Stable");
// ------------------------------- Not stable
int min;
int minn = 0;
for(int i = 0; i < n - 1; i++) {
min = mem[i][1];
for(int j = 1 + i; j < n; j++) {
if((int)mem[j][1] < min) {
min = (int)mem[j][1];
minn = j;
}
}
if((int)mem[i][1] != min) {
Swap(ref mem[i], ref mem[minn]);
}
}
for(int i = 0; i < n; i++) {
if(i != n - 1)
Console.Write(mem[i] + " ");
else
Console.WriteLine(mem[i]);
}
string mem_str = "";
string arr_str = "";
for(int i = 0; i < n; i++) {
mem_str += mem[i];
arr_str += arr[i];
}
if(mem_str.CompareTo(arr_str) == 0)
Console.WriteLine("Stable");
else
Console.WriteLine("Not stable");
}
static void Swap(ref string x, ref string y) {
string comp = x;
x = y;
y = comp;
return;
}
}
Python3版本:
N = int(input())
B = input().split()
S = B[:]
for i in range(N):
for j in range(N-1, i, -1):
if B[j][1] < B[j-1][1]:
B[j], B[j-1] = B[j-1], B[j]
m = i
for j in range(i, N):
if S[m][1] > S[j][1]:
m = j
S[m], S[i] = S[i], S[m]
print(*B)
print('Stable')
print(*S)
print(['Not s', 'S'][B==S] + 'table')
PHP版本:
<?php
$N=(int)fgets(STDIN);
$Ab=$As=explode(' ',trim(fgets(STDIN)));
for($i=0;$i<$N;$i++)
for($j=$N-1;$i<$j;$j--)
if($Ab[$j][1]<$Ab[$j-1][1]) list($Ab[$j],$Ab[$j-1])=[$Ab[$j-1],$Ab[$j]];
for($i=0;$i<$N;$i++){
for($mini=$j=$i;$j<$N;$j++)
if($As[$j][1]<$As[$mini][1]) $mini=$j;
if($i!=$mini) list($As[$i],$As[$mini])=[$As[$mini],$As[$i]];
}
$diff=0;
for($i=0;$i<$N;$i++)
if($Ab[$i]!=$As[$i]){$diff=1;break;}
$sAb=implode(' ',$Ab);
echo $sAb,PHP_EOL,'Stable',PHP_EOL;
if($diff) echo implode(' ',$As),PHP_EOL,'Not stable';
else echo $sAb,PHP_EOL,'Stable';
?>
JavaScript版本:
var input = require('fs').readFileSync('/dev/stdin', 'utf8');
var lines = input.split('\n');
var n = lines[0];
var A1 = lines[1].split(' ');
for (var i = 0; i < n; i++) {
for (var j = n - 1; j > i; j--) {
if (A1[j].split('')[1] < A1[j - 1].split('')[1]) {
var tmp = A1[j];
A1[j] = A1[j - 1];
A1[j - 1] = tmp;
}
}
}
console.log(A1.join(' '));
console.log('Stable');
var A2 = lines[1].split(' ');
for (var i = 0; i < n; i++) {
var min = i;
for (var j = i; j < n; j++) {
if (A2[j].split('')[1] < A2[min].split('')[1])
min = j;
}
if (min == i)
continue;
var tmp = A2[i];
A2[i] = A2[min];
A2[min] = tmp;
}
console.log(A2.join(' '));
console.log(A1.join(' ') == A2.join(' ') ? 'Stable' : 'Not stable');