第四章演算法實踐
1.實踐題目
7-1 最優合併問題 (100 分)
題目來源:王曉東《演算法設計與分析》
給定k 個排好序的序列, 用 2 路合併演算法將這k 個序列合併成一個序列。 假設所採用的 2 路合併演算法合併 2 個長度分別為m和n的序列需要m+n-1 次比較。試設 計一個演算法確定合併這個序列的最優合併順序,使所需的總比較次數最少。 為了進行比較,還需要確定合併這個序列的最差合併順序,使所需的總比較次數最多。
輸入樣例:
4
5 12 11 2
輸出樣例:
78 52
2.問題描述
將幾個序列合併成一個序列,序列的比較次數的計算方式是序列長度分別為m和n的序列為m+n-1 次。計算最多比較次數時,從待選序列中選取最長的兩個序列合併成新的序列,繼續比較合併直至合併成最終序列,同理於最少比較次數的方法,只是合併最短序列。
程式碼如下:
#include<iostream>
using namespace std;
int getmax(int a[],int n){
int number=n,result=0,s[n];
int i,j,temp;
for(i=0;i<n;i++){
s[i]=a[i];
}
while(number>1){
for(i=0;i<number;i++){
for(j=i+1;j<number;j++){
if(s[i]<s[j]){
temp=s[i];s[i]=s[j];s[j]=temp;
}
}
}
s[0]=s[0]+s[1];
result+=s[0]-1;
number--;
for(i=1;i<number;i++)
s[i]=s[i+1];
}
return result;
}
int getmin(int a[],int n){
int number = n,result=0,s[n];
int i,j,temp;
for(i=0; i<n; i++){
s[i]=a[i];
}
while(number>1){
for(i=0;i<number;i++){
for(j=i+1;j<number;j++){
if(s[i]>s[j]){
temp=s[i];s[i]=s[j];s[j]=temp;
}
}
}
s[0]=s[0]+s[1];
result+=s[0]-1;
number--;
for(i=1;i<number;i++)
s[i]=s[i+1];
}
return result;
}
int main()
{
int n;
cin >> n;
int *a = new int[n];
for(int i=0;i<n;i++)
{
cin >> a[i];
}
cout << getmax(a,n) << " " <<getmin(a,n);
return 0;
}
3.
時間複雜度:O(nlongn)
空間複雜度:O(n)
4.心得:感覺這道,題跟之前幾道實踐題類似,在最開始寫演算法時,編寫了冒泡演算法,雖然可以計算正確,演算法的操作時間和程式碼數都不少,較為冗餘。自己編寫的演算法缺點很明顯,在編寫演算法程式碼這方面較為薄弱,下次還要繼續改進