浙大数据结构第二版——习题3.6 一元多项式的乘法与加法运算
·
测试链表
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//定义链表
typedef struct LNode {
int x;
int z;
struct LNode* next;
}LNode, * PtrNode;//同时为结构体,结构体指针重定义
//长度
int length(PtrNode L) {
PtrNode p = L->next;
int cnt = 0;
while (p) {
cnt++;
p = p->next;
}
return cnt;
}
//初始化
PtrNode Init() {
PtrNode L = (PtrNode)malloc(sizeof(LNode));
L->next = NULL;
return L;
}
//头插法
void InsertHead(PtrNode L, int x, int z) {
PtrNode p = L->next;
PtrNode q = (PtrNode)malloc(sizeof(LNode));
q->x = x;
q->z = z;
q->next = p;
L->next = q;
}
//尾插法
void InsertTail(PtrNode L, int x, int z) {
PtrNode p = L;
while (p->next) {
p = p->next;
}
PtrNode q = (PtrNode)malloc(sizeof(LNode));
q->x = x;
q->z = z;
q->next = NULL;
p->next = q;
}
//测试
int main() {
PtrNode L1 = Init();
PtrNode L2 = Init();
int n1,n2;
scanf("%d", &n1);
for (int i = 0; i < n1; i++) {
int x, z;
scanf("%d %d", &x, &z);
InsertTail(L1, x, z);
}
scanf("%d", &n2);
for (int i = 0; i < n2; i++) {
int x, z;
scanf("%d %d", &x, &z);
InsertHead(L2, x, z);
}
PtrNode p1 = L1->next;
while (p1) {
printf("%d %d\n", p1->x, p1->z);
p1 = p1->next;
}
printf("%d\n", length(L1));
PtrNode p2 = L2->next;
while (p2) {
printf("%d %d\n", p2->x, p2->z);
p2 = p2->next;
}
printf("%d\n", length(L2));
}
输入:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出:3 4
-5 2
6 1
-2 0
4
3 1
-7 4
5 20
3
习题3.6 一元多项式的乘法与加法运算
习题3.6 一元多项式的乘法与加法运算 - 浙大版《数据结构(第2版)》题目集


一、链表思路
1.由于最后降序排列,并且要合并指数相同的项,要移动较多元素。首先想到使用带头结点的单向链表(若限制指数大小,使用线性表+哈希表会更方便)。
2.使用链表L1,L2分别存储两个多项式。
3.对于乘法,使用L3保存结果。对于加法,直接使用L1存储结果即可。
4.乘法和除法在加入新项(q)时的思路是一致的,设保存结果的链表为L。
(1)L为空,则直接尾插即可。
(2)L不为空,则使用指针k(前驱),p(后继)从头遍历链表,直到指针p的指数小于等于q的指数。
a.L内所有项的指数均大于q的指数,此时p=NULL:k->next=q。
b.p的指数小于q的指数:q->next=p;k->next=q;
c.p的指数等于q的指数:p->x+=x;(x为系数)
注:健壮性考虑
1.同类项合并时有抵消
针对情况4.(2).b:若合并完成后q->x==0,则应该舍弃这个系数为0的项。
2.系数和指数取上限,结果有零多项式
输出时判断结果中,每项系数x是否全为0即可。遇到0多项式则输出0 0。
3.输入有零多项式和常数多项式
针对4.(2):面对新项时,判断其系数是否为0,为0则舍弃该项。
二、链表完整代码
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode{
int x;
int z;
struct LNode* next;
}LNode,*PtrLNode;
int Length(PtrLNode L){
PtrLNode p=L->next;
int cnt=0;
while(p){
cnt++;
p=p->next;
}
return cnt;
}
//初始化
PtrLNode Init(){
PtrLNode L=(PtrLNode)malloc(sizeof(LNode));
L->next=NULL;
return L;
}
//尾插法
void InsertTail(PtrLNode L,int x,int z){
PtrLNode p=L;
while(p->next){
p=p->next;
}
PtrLNode q=(PtrLNode)malloc(sizeof(LNode));
q->x=x;
q->z=z;
q->next=NULL;
p->next=q;
}
//创造新结点
PtrLNode create(int x,int z){
PtrLNode q=(PtrLNode)malloc(sizeof(LNode));
q->x=x;
q->z=z;
//必须指向空
q->next=NULL;
return q;
}
//插入新项
void InsertL3(PtrLNode L3,int x,int z){
if(x==0){
return;
}
PtrLNode p3=L3->next;
PtrLNode k=L3;
while(p3!=NULL&&p3->z>z){
k=p3;
p3=p3->next;
}
if(p3!=NULL&&p3->z==z){
//相同则合并
p3->x+=x;
//合并后系数为零则舍弃
if(p3->x==0){
k->next=p3->next;
free(p3);
}
}
else{
//插入新节点(表头,表中,表尾)
PtrLNode q=create(x,z);
q->next=p3;
k->next=q;
}
}
//乘
void muilty(PtrLNode L1,PtrLNode L2,PtrLNode L3){
PtrLNode p1;
PtrLNode p2;
int xx,zz;
for(p1=L1->next;p1!=NULL;p1=p1->next){
for(p2=L2->next;p2!=NULL;p2=p2->next){
xx=p1->x*p2->x;
zz=p1->z+p2->z;
InsertL3(L3,xx,zz);
}
}
}
//加
void sum(PtrLNode L1,PtrLNode L2){
PtrLNode p2=L2->next;
while(p2){
InsertL3(L1,p2->x,p2->z);
p2=p2->next;
}
}
//输出(保持健壮性)
void PrintPoly(PtrLNode L){
PtrLNode p;
int isfirst=1;
int value=0;
for(p=L->next;p!=NULL;p=p->next){
if(p->x!=0){
value=1;
if(isfirst){
printf("%d %d",p->x,p->z);
isfirst=0;
}else{
printf(" %d %d",p->x,p->z);
}
}
}
if(value==0){
printf("0 0");
}
}
int main(){
PtrLNode L1=Init();
PtrLNode L2=Init();
PtrLNode L3=Init();
int n1,n2,x,z;
scanf("%d",&n1);
for(int i=0;i<n1;i++){
scanf("%d %d",&x,&z);
InsertTail(L1,x,z);
}
scanf("%d",&n2);
for(int i=0;i<n2;i++){
scanf("%d %d",&x,&z);
InsertTail(L2,x,z);
}
//多项式乘法L1*L2=L3
muilty(L1,L2,L3);
//多项式加法L1+L2=L1
sum(L1,L2);
//输出
PrintPoly(L3);
printf("\n");
PrintPoly(L1);
}
最终好结局

三、顺序表思路
注意到题目中,指数范围大于等于0,且小于1000,只要搞一个较大的数组p[2005],用哈希表即可简单解决
四、顺序表代码
#include<stdio.h>
#include<stdlib.h>
typedef struct poly{
int x;
int z;
}poly,*Ppoly;
void muiltiple(Ppoly p1,Ppoly p2, Ppoly p3,int n1,int n2){
int xx,zz;
for(int i=0;i<n1;i++){
for(int j=0;j<n2;j++){
xx=p1[i].x*p2[j].x;
zz=p1[i].z+p2[j].z;
p3[zz].x+=xx;
p3[zz].z=zz;
}
}
}
void sum(Ppoly p1,Ppoly p2,Ppoly p4,int n1, int n2){
int xx,zz;
for(int i=0;i<n1;i++){
xx=p1[i].x;
zz=p1[i].z;
p4[zz].x+=xx;
p4[zz].z=zz;
}
for(int i=0;i<n2;i++){
xx=p2[i].x;
zz=p2[i].z;
p4[zz].x+=xx;
p4[zz].z=zz;
}
}
void printPoly(Ppoly p){
int value=0;
int isfirst=1;
for(int i=2004;i>=0;i--){
if(p[i].x!=0){
value=1;
if(isfirst){
printf("%d %d",p[i].x,p[i].z);
isfirst=0;
}else{
printf(" %d %d",p[i].x,p[i].z);
}
}
}
if(value==0){
printf("0 0");
}
}
int main(){
int n1,n2;
scanf("%d",&n1);
poly p1[2005]={0},p2[2005]={0},p3[2005]={0},p4[2005]={0};
for(int i=0;i<n1;i++){
scanf("%d %d",&p1[i].x,&p1[i].z);
}
scanf("%d",&n2);
for(int i=0;i<n2;i++){
scanf("%d %d",&p2[i].x,&p2[i].z);
}
muiltiple(p1,p2,p3,n1,n2);
sum(p1,p2,p4,n1,n2);
printPoly(p3);
printf("\n");
printPoly(p4);
}更多推荐
所有评论(0)