上机 04实验名称
一、1
1、 描述
一、最 合并
定 k 个有序序列 s1 , s2,... , sk , 用 2 路合并算法将 k 个序列合并成一个序列。 假 所采用的 2 路合并算法合并 2 个 度分 m 和 n 的序列需要 m + n -1 次比 。 一个算法确定合并 个序列的最 合并 序,使所需的 比 次数最少, 程 算法并 明算法的正确性。
2、 算法 思想
心算法
3、 算法 程描述
原 S={S1, S2, S3, S4..Sn},(合并 序)
最 解 Ck(最少合并次数 )
Si,Sj 最短的两个序列反 法 明 心 性 :
有另一个最 解 Ck1(没有使用 心 性 ,即没有先合并构造一 二叉合并
Si,Sj)
Sk 任意序列,Sk>si,sj
Si
SkSSj
Sk
SiSj
由 可知, Ck-Ck1=(Sk+Sj-1)+(Si+Sj+si-1)-(Si+sj-1)+(Si+Sj+Sk-1)=Sk-Si>0 因此 Ck1 不是最 解,因此具有 心 性 最 子 构 明:
S={S1, S2, S3, S4? .Sn}
Si 和 Sj 的合并 ( Si,Sj) ->Si+j
S=S-{S1,S2}∪ Si+j
Ck=Ck`+(Si+Sj-1)
4、 算法 及运行 果
#include
#include
using namespace std;
算最
int minSum(int *a,int m){
int b[m];
int sum=0;
for(int i=0;i
b[i]=a[i];
}
while(m>1){
sort(b,b+m);
b[0]=b[1]+b[0];
sum+=b[0] -1;
for(int i=1;i
b[i]=b[i+1];
m--;
}
return sum;
}
int main (){
int n;
printf(" 请输入序列个数:\n");
scanf("%d",&n);
int a[n+1];
printf(" 请输入各个序列长度:\n");
for(int i=0;i
scanf("%d",&a[i]);
}
printf(" 最少比较次数为:%d\n",minSum(a,n));
return 0;
}
5、 算法复杂度分析及算法改进
时间复杂度:排序:O(nlogn),合并 (n-1)(2*O(1)+O(n))=O(n^2)
使用堆排序:( n-1) (2*O(logn)+O(logn))=O(nlogn)