讲解
由于本题中的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');