数据结构系列内容的学习目录 → \rightarrow →浙大版数据结构学习系列内容汇总。
4. 应用实例
4.1 多项式加法运算
例: 将多项式 P 1 = 3 x 5 + 4 x 4 − x 3 + 2 x − 1 P_{1}=3x^{5}+4x^{4}-x^{3}+2x-1 P1=3x5+4x4−x3+2x−1与 P 2 = 2 x 4 + x 3 − 7 x 2 + 3 x − 1 P_{2}=2x^{4}+x^{3}-7x^{2}+3x-1 P2=2x4+x3−7x2+3x−1进行相加。
主要思路: 相同指数的项系数相加,其余部分进行拷贝。
采用不带头结点的单向链表,按照指数递减的顺序排列各项。
struct PolyNode {
int coef; //系数
int expon; //指数
struct PolyNode *link; //指向下一个节点的指针
};
typedef struct PolyNode *Polynomial;
Polynomial P1,P2;
算法思路: 两个指针P1和P2分别指向这两个多项式第一个结点,不断循环:
⋄
\diamond
⋄ P1->expon==P2>expon
:系数相加,若结果不为0,则作为结果多项式对应项的系数。同时,P1和P2都分别指向下一项;
⋄
\diamond
⋄ P1->expon>P2->expon
:将P1的当前项存入结果多项式,并使P1指向下一项;
⋄
\diamond
⋄ P1->expon<P2->expon
:将P2的当前项存入结果多项式,并使P2指向下一项。
当某一多项式处理完时,将另一个多项式的所有结点依次复制到结果多项式中去。
Polynomial PolyAdd(Polynomial P1,Polynomial P2)
{
Polynomial front, rear, temp; //为方便表头插入,先产生一个临时空结点作为结果多项式链表头
int sum;
rear = (Polynomial) malloc(sizeof(struct PolyNode));
front = rear; //由front记录结果多项式链表头结点
while (P1 && P2) //当两个多项式都有非零项待处理时
{
switch (Compare(P1->expon, P2->expon))
{
case 1: //P1中的数据项指数较大
Attach(P1->coef, P1->expon, &rear);
P1 = P1->link;
break;
case -1: //P2中的数据项指数较大
Attach(P2->coef, P2->expon, &rear);
P2 = P2->link;
break;
case 0: //两数据项指数相等
sum = P1->coef + P2->coef;
if (sum) //注意判断系数和是否为0
Attach(sum, P1->expon, &rear);
P1 = P1->link;
P2 = P2->link;
break;
}
}
//将未处理完的另一个多项式的所有节点依次复制到结果多项式中去
for(; P1; P1=P1->link) //P1不为空
Attach(P1->coef,P1->expon, &rear);
for(; P2; P2= P2->link ) //P2不为空
Attach(P2->coef,P2->expon, &rear);
rear->link = NULL;
temp= front;
front= front->link; //令front指向结果多项式第一个非零项
free(temp); //释放临时空表头结点
return front;
}
新增一个结点的实现。
// 新增一个节点
void Attach(int c, int e, Polynomial*pRear) //由于在本函数中需要改变当前结果表达式尾项指针的值,所以函数传递进来的是结点指针的地址,*pRear指向尾项
{
Polynomial P;
P=(Polynomial)malloc(sizeof(struct PolyNode)); //申请新结点
P->coef = c; //对新结点赋值
P->expon = e;
P->link=NULL; //将P指向的新结点插入到当前结果表达式尾项的后面
(*pRear)->link = P;
*pRear = P; //修改pRear值
}
多项式加法运算的完整实现代码如下所示。
#include<iostream>
using namespace std;
struct PolyNode {
int coef; //系数
int expon; //指数
struct PolyNode *link; //指向下一个节点的指针
};
typedef struct PolyNode *Polynomial;
Polynomial P1, P2;
Polynomial PolyAdd(Polynomial P1, Polynomial P2);
void Attach(int c, int e, Polynomial *pRear);
int Compare(int a, int b);
void PrintPoly(Polynomial P);
Polynomial PolyAdd(Polynomial P1, Polynomial P2)
{
Polynomial front, rear, temp;
int sum;
rear = (Polynomial)malloc(sizeof(struct PolyNode)); //为方便表头插入,先产生一个临时空结点作为结果多项式链表头
front = rear; //由front记录结果多项式链表头结点
while (P1 && P2) //当两个多项式都有非零项待处理时
{
switch (Compare(P1->expon, P2->expon))
{
case 1: //P1中的数据项指数较大
Attach(P1->coef, P1->expon, &rear);
P1 = P1->link;
break;
case -1: //P2中的数据项指数较大
Attach(P2->coef, P2->expon, &rear);
P2 = P2->link;
break;
case 0: //两数据项指数相等
sum = P1->coef + P2->coef;
if (sum) //注意判断系数和是否为0
Attach(sum, P1->expon, &rear);
P1 = P1->link;
P2 = P2->link;
break;
}
}
//将未处理完的另一个多项式的所有节点依次复制到结果多项式中去
for (; P1; P1 = P1->link) //P1不为空
Attach(P1->coef, P1->expon, &rear);
for (; P2; P2 = P2->link) //P2不为空
Attach(P2->coef, P2->expon, &rear);
rear->link = NULL;
temp = front;
front = front->link; //令front指向结果多项式第一个非零项
free(temp); //释放临时空表头结点
return front;
}
int Compare(int a, int b)
{
if (a > b)
return 1;
else if (a < b)
return -1;
else
return 0;
}
// 新增一个节点
void Attach(int c, int e, Polynomial *pRear) //由于在本函数中需要改变当前结果表达式尾项指针的值,所以函数传递进来的是结点指针的地址,*pRear指向尾项
{
Polynomial P;
P = (Polynomial)malloc(sizeof(struct PolyNode)); //申请新结点
P->coef = c; //对新结点赋值
P->expon = e;
P->link = NULL;
//将P指向的新结点插入到当前结果表达式尾项的后面
(*pRear)->link = P; // 尾节点指向P
*pRear = P; //修改pRear指针指向的值
}
void PrintPoly(Polynomial P)
{
Polynomial tmp = P;
for (; tmp; tmp = tmp->link)
{
cout << tmp->coef << " " << tmp->expon << " ";
}
cout << endl;
}
int main()
{
int P1Coef[5] = { 3, 4, -1, 2, -1 };
int P1expon[5] = { 5, 4, 3, 1, 0 };
int P2Coef[4] = { 2, 1, -7, 1 };
int P2expon[4] = { 4, 3, 2, 1 };
P1 = (Polynomial)malloc(sizeof(struct PolyNode));
P2 = (Polynomial)malloc(sizeof(struct PolyNode));
Polynomial P1Rear;
P1Rear = P1;
Polynomial P2Rear;
P2Rear = P2;
for (int i = 0; i < 5; ++i)
{
Attach(P1Coef[i], P1expon[i], &P1Rear); // 注意这里传的是地址!!!
}
P1 = P1->link; // 因为第一个节点没有存储数据,所以 P1 要往后挪一位
for (int i = 0; i < 4; ++i)
{
Attach(P2Coef[i], P2expon[i], &P2Rear);
}
P2 = P2->link;
Polynomial res = PolyAdd(P1, P2);
cout << "P1: ";
PrintPoly(P1);
cout << "P2: ";
PrintPoly(P2);
cout << "P1+P2:";
PrintPoly(res);
system("pause");
return 0;
}
代码运行结果如下图所示。
4.2 一元多项式的加法与乘法运算
题意理解: 设计函数分别求两个一元多项式的乘积与和。
已知两个多项式:
P
1
=
3
x
4
−
5
x
2
+
6
x
−
2
P_{1}=3x^{4}-5x^{2}+6x-2
P1=3x4−5x2+6x−2,
P
2
=
5
x
20
−
7
x
4
+
3
x
P_{2}=5x^{20}-7x^{4}+3x
P2=5x20−7x4+3x
P
1
+
P
2
=
5
x
20
−
4
x
4
−
5
x
2
+
9
x
−
2
P_{1}+P_{2}=5x^{20}-4x^{4}-5x^{2}+9x-2
P1+P2=5x20−4x4−5x2+9x−2
多项式的乘积:
(
a
+
b
)
(
c
+
d
)
=
a
c
+
a
d
+
b
c
+
b
d
(a+b)(c+d)=ac+ad+bc+bd
(a+b)(c+d)=ac+ad+bc+bd
P
1
⋅
P
2
=
15
x
24
−
25
x
22
+
30
x
21
−
10
x
20
−
21
x
8
+
35
x
6
−
33
x
5
+
14
x
4
−
15
x
3
+
18
x
2
−
6
x
P_{1}\cdot P_{2}=15x^{24}-25x^{22}+30x^{21}-10x^{20}-21x^{8}+35x^{6}-33x^{5}+14x^{4}-15x^{3}+18x^{2}-6x
P1⋅P2=15x24−25x22+30x21−10x20−21x8+35x6−33x5+14x4−15x3+18x2−6x
多项式的表示: 仅表示非零项。
数组:1. 编程简单、调试容易;
2. 需要事先确定数组大小。
链表:1. 动态性强;
2. 编程略为复杂、调试比较困难。
一种比较好的实现方法是:动态数组。
使用链表表示的数据结构设计如下所示。
typedef struct PolyNode *Polynomial;
struct PolyNode {
int coef;
int expon;
Polynomial link;
};
程序框架搭建:
int main()
{
读入多项式1
读入多项式2
乘法运算并输出
加法运算并输出
return 0;
}
需要设计的函数: 1. 读入多项式
2. 两多项式相乘
3. 两多项式相加
4. 多项式输出
一元多项式的加法与乘法运算的完整实现代码如下所示。
#include<iostream>
using namespace std;
typedef struct PolyNode {
int coef;//系数
int exp;//指数
struct PolyNode *next;
} *Polynomial;
Polynomial read(Polynomial P);
void print(Polynomial P);
Polynomial getMuti(Polynomial P1, Polynomial P2);
Polynomial getAdd(Polynomial P1, Polynomial P2);
Polynomial read(Polynomial P)
{
Polynomial s = NULL, temp;
P = (struct PolyNode*)malloc(sizeof(struct PolyNode));
temp = P;
int n, COEF, EXP;
cout << "多项式的项数:";
cin >> n;
cout << "多项式每项对应的系数和指数:";
for (int i = 0; i < n; i++)
{
cin >> COEF >> EXP;
if (COEF != 0)
{
s = (struct PolyNode *)malloc(sizeof(struct PolyNode));
s->coef = COEF;
s->exp = EXP;
P->next = s;
P = s;
}
}
P->next = NULL;
return temp;
}
void print(Polynomial P)
{
int num = 0, temp = 0; //temp用于统计P里面有多少个元素,num 用于统计有多少个系数为0的数
Polynomial val = P;
while (val->next)
{
val = val->next;
temp++;
}
if (P->next != NULL)
{
while (P->next)
{
if (P->next->coef != 0)
{
cout << P->next->coef << " " << P->next->exp;
Polynomial val = P->next;
while (val->next&&val->next->coef == 0)
{
val = val->next;
}
if (val->next == NULL)
cout << endl;
else
cout << " ";
}
else
num++;
P = P->next;
}
if (num == temp)
cout << 0 << " " << 0 << endl;
}
else
cout << 0 << " " << 0 << endl;
}
Polynomial getAdd(Polynomial P1, Polynomial P2)
{
Polynomial P, temp = NULL, s = NULL;
P = (struct PolyNode *)malloc(sizeof(struct PolyNode));
temp = P;
while (P1->next&&P2->next)
{
if (P1->next->exp > P2->next->exp)
{
s = (struct PolyNode *)malloc(sizeof(struct PolyNode));
s->coef = P1->next->coef;
s->exp = P1->next->exp;
P->next = s;
P = s;
P1 = P1->next;
}
else if (P1->next->exp < P2->next->exp)
{
s = (struct PolyNode *)malloc(sizeof(struct PolyNode));
s->coef = P2->next->coef;
s->exp = P2->next->exp;
P->next = s;
P = s;
P2 = P2->next;
}
else
{
s = (struct PolyNode *)malloc(sizeof(struct PolyNode));
s->coef = P2->next->coef + P1->next->coef;
s->exp = P2->next->exp;
P->next = s;
P = s;
P1 = P1->next;
P2 = P2->next;
}
}
if (P1->next)
P->next = P1->next;
else
P->next = P2->next;
return temp;
}
Polynomial getMuti(Polynomial P1, Polynomial P2) {
/*
在这里我们采用的是:逐项插入。
1,先拿出P2的第一项,让它与P1的每一项相乘,从而得到P
2,再拿出P2的第二项,让它与P1的每一项相乘,然后每乘一项,就将其插入到P中
3,依次重复上面的步骤,最终得到P,将其打印出来
*/
Polynomial P, temp = NULL, s = NULL;
P = (struct PolyNode *)malloc(sizeof(struct PolyNode));
temp = P;
Polynomial Pa = P1;
//拿出P2的第一项,让它与P1的每一项相乘,从而得到P
while (Pa->next) {
s = (struct PolyNode *)malloc(sizeof(struct PolyNode));
s->coef = Pa->next->coef * P2->next->coef; //P1的每一项与P2的第一项的系数相乘
s->exp = Pa->next->exp + P2->next->exp; //P1的每一项与P2的第一项的指数相加
P->next = s;
P = s;
Pa = Pa->next;
}
P->next = NULL;
P = temp;
Polynomial Pb = P2->next;
while (Pb&&Pb->next)
{
Pa = P1;
while (Pa->next)
{
s = (struct PolyNode *)malloc(sizeof(struct PolyNode));
s->coef = Pa->next->coef * Pb->next->coef;
s->exp = Pa->next->exp + Pb->next->exp;
while (P->next)
{
if (s->exp > P->next->exp)
{
Polynomial val = P->next;
P->next = s;
s->next = val;
break;
}
else if (s->exp == P->next->exp)
{
P->next->coef += s->coef;
break;
}
P = P->next;
}
if (P->next == NULL)
{
P->next = s;
s->next = NULL;
}
P = temp;
Pa = Pa->next;
}
Pb = Pb->next;
}
return temp;
}
int main()
{
Polynomial P1 = NULL;
Polynomial P2 = NULL;
Polynomial P = NULL;
cout << "P1:" << endl;
P1 = read(P1);
cout << "P2:" << endl;
P2 = read(P2);
cout << "P1*P2:";
P = getMuti(P1, P2);
print(P);
cout << "P1+P2:";
P = getAdd(P1, P2);
print(P);
system("pause");
return 0;
}
代码运行结果如下图所示。