【练习3.7】
编写一个函数将两个多项式相乘,用一个链表实现。你必须保证输出的多项式按幂次排列,并且任意幂次最多只有一项。
a.给出以O(M2N2)时间求解该问题的算法。
b.写一个以O(M2N)时间执行乘法的程序,其中M≤N。
c.写一个以O(MNlog(MN))时间执行乘法的程序。
d.上面哪个时间界最好?
Answer:
【a】.将两链表元素两两相乘并列出,从第一项开始,依次与其后的所有项比较,如相等则合并。
合并完成后,每次找出幂次最小的项,插入链表。(最原始的方法)
【b】.M≤1时,方法易知。
M≥2时,每次将长度为M的链表的一项,与另一链表的所有项相乘,每次一组N个有序的多项式元素。
对于每两组上式的N个多项式元素,基本按练习3.5有序链表求并的算法(除幂次相同需将系数相加)操作。
求并算法时间复杂度O(M+N),故该算法复杂度为
(乘法时间)O(MN)+(求并时间)O((N+N)+(2N+N)+(3N+N)+……+(MN+N))=O(M2N)
【详情见代码】
【c】.同a先将两链表元素两两相乘并列出,对MN项元素进行O(NlogN)的排序
排序完成后,遍历代码,合并同幂次项,最后全部插入链表。时间复杂度为:
(乘法时间)O(MN)+(排序时间)O(MNlogMN)+(合并同类项时间)O(MN)=O(MNlogMN)
【详见代码】
代码部分,首先是测试代码,b和c的测试代码写在一起了
1 #include <iostream> 2 #include "linklist.h" 3 using linklist::List; 4 using namespace std; 5 int main(void) 6 { 7 //测试多项式加法 8 List<Poly> a; 9 a.additem(Poly(3, 1)); 10 a.additem(Poly(1, 2)); 11 a.additem(Poly(4, 3)); 12 a.additem(Poly(7, 4)); 13 a.additem(Poly(2, 5)); 14 cout << " ( " << flush; 15 a.traverse(); 16 cout << ") +\n" << flush; 17 List<Poly> b; 18 b.additem(Poly(5, 2)); 19 b.additem(Poly(2, 3)); 20 b.additem(Poly(1, 5)); 21 b.additem(Poly(3, 7)); 22 b.additem(Poly(1, 11)); 23 cout << " ( " << flush; 24 b.traverse(); 25 cout << ") =\n" << flush; 26 27 List<Poly> answer = linklist::polymulti_seq(a, b); 28 List<Poly> another = linklist::polymulti_sort(a, b); 29 cout << "\n ( " << flush; 30 answer.traverse(); 31 cout << ") \n" << flush; 32 33 cout << "\n ( " << flush; 34 another.traverse(); 35 cout << ") \n" << flush; 36 system("pause"); 37 }