一、实验目的(本次实验所涉及并要求掌握的知识点)
掌握顺序表和单链表的存储表示和运算的实现,并运用基本运算完成复杂的功能。
二、实验内容与设计思想(设计思路、主要数据结构、主要代码结构、主要代码段分析)
1. 实验内容
采用单链表存储一元多项式,设计完成如下功能的算法并用相关数据进行测试。
- 输入并建立多项式;
- 输出多项式,其中每一项按照指数降序排列;
- 求两个多项式的加法运算;
- 求两个多项式的减法运算;
- 求两个多项式的乘法运算
2. 抽象数据类型定义
ADT poly
{
数据对象:一元多项式
数据关系:多项式
基本运算:
void createPolynomial(Node** poly);// 创建多项式
void displayPolynomial(Node* poly);// 输出多项式
void freePolynomial(Node* poly);// 释放多项式的内存
Node* addPolynomials(Node* polyA, Node* polyB);// 多项式相加
Node* subtractPolynomials(Node* polyA, Node* polyB);// 多项式相减
Node* multiplyPolynomials(Node* polyA, Node* polyB);// 多项式相乘
Node* simplifyPolynomial(Node* poly);// 化简多项式,合并同类项并去除系数为 0 的项
}
3. 设计思路
使用单链表来存储一元多项式,并实现了以下功能:
1、定义数据结构:使用一个结构体 Node 来表示多项式的每一项,其中包括系数和指数,并使用一个指针 next 指向下一项。这样就可以通过链表的形式来存储整个多项式。
2、创建多项式:使用函数 createPolynomial ,先获取用户输入的项数,然后逐一输入每一项的系数和指数,并创建新的节点加入链表中。
3、显示多项式:使用函数 displayPolynomial,遍历链表并输出每一项的系数和指数。
4、多项式相加:使用函数 addPolynomials ,使用了一个循环来遍历两个多项式链表,并根据指数的大小关系进行相应的操作。
5、多项式相减:使用函数subtractPolynomials,使用了一个循环来遍历两个多项式链表,并根据指数的大小关系进行相应的操作。
6、多项式相乘:使用函数 multiplyPolynomials ,通过两个循环遍历两个多项式链表的每一项,并将每一项的系数和指数相乘,得到新的节点加入临时的结果链表中。然后调用 addPolynomials 函数将临时结果链表和最终结果链表相加,最后释放临时结果链表的内存。
7、化简多项式:使用函数simplifyPolynomial,首先判断多项式是否为空,若为空则直接返回。然后使用两个指针current和prev来遍历多项式链表。在合并同类项的过程中,我们从头部开始,依次比较当前节点和后续节点的指数。若两个节点的指数相同,则将它们的系数相加,并删除后续节点。删除节点后,current指针不移动,继续比较当前节点和下一个节点。在删除系数为0的项的过程中,我们同样使用两个指针current和prev来遍历多项式链表。若当前节点的系数为0,则将该节点从链表中删除。删除节点后,current指针不移动,继续比较当前节点和下一个节点。最后,函数返回化简后的多项式链表。
这样,通过合并同类项和删除系数为0的项,我们可以将多项式化简为简洁形式。
4. 数据结构定义
// 定义多项式的节点结构
typedef struct Node {
int coefficient; // 系数
int exponent; // 指数
struct Node* next; // 指向下一个节点的指针
} Node;
void createPolynomial(Node** poly);// 创建多项式
void displayPolynomial(Node* poly);// 输出多项式
void freePolynomial(Node* poly);// 释放多项式的内存
Node* addPolynomials(Node* polyA, Node* polyB);// 多项式相加
Node* subtractPolynomials(Node* polyA, Node* polyB);// 多项式相减
Node* multiplyPolynomials(Node* polyA, Node* polyB);// 多项式相乘
Node* simplifyPolynomial(Node* poly);// 化简多项式,合并同类项并去除系数为 0 的项
5. 程序中各函数调用关系及主要功能函数流程图
在main.c中调用以下函数实现操作:
调用 createPolynomial 函数:创建多项式 A 和多项式 B。
调用 displayPolynomial 函数:显示多项式 A 和多项式 B。
调用 addPolynomials 函数:进行多项式相加操作,并调用 displayPolynomial 函数显示结果。
调用 subtractPolynomials 函数:进行多项式相减操作,并调用 displayPolynomial 函数显示结果。
调用 multiplyPolynomials 函数:进行多项式相乘操作,并调用 displayPolynomial 函数显示结果。
调用simplifyPolynomial函数:化简多项式,合并同类项并去除系数为 0 的项,通过运算将指数相同的项化简
三、实验使用环境(本次实验所使用的平台和相关软件)
Visual stdio
四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)
1. 测试数据
创建多项式 A:
请输入多项式的项数:3
请依次输入每一项的系数和指数:
第 1 项:-7
1
第 2 项:6
0
第 3 项:3
5
创建多项式 B:
请输入多项式的项数:4
请依次输入每一项的系数和指数:
第 1 项:2
2
第 2 项:7
1
第 3 项:-4
5
第 4 项:2
0
2. 程序运行结果截图
五、附录代码
//poly.h
// 定义多项式的节点结构
typedef struct Node {
int coefficient; // 系数
int exponent; // 指数
struct Node* next; // 指向下一个节点的指针
} Node;
void createPolynomial(Node** poly);// 创建多项式
void displayPolynomial(Node* poly);// 输出多项式
void freePolynomial(Node* poly);// 释放多项式的内存
Node* addPolynomials(Node* polyA, Node* polyB);// 多项式相加
Node* subtractPolynomials(Node* polyA, Node* polyB);// 多项式相减
Node* multiplyPolynomials(Node* polyA, Node* polyB);// 多项式相乘
Node* simplifyPolynomial(Node* poly);// 化简多项式,合并同类项并去除系数为 0 的项
//poly.c
#include <stdio.h>
#include <stdlib.h>
#include "poly.h"
// 创建多项式
void createPolynomial(Node** poly) {
int terms;
int coefficient, exponent;
Node* tail = NULL;
printf("请输入多项式的项数:");
scanf("%d", &terms);
printf("请依次输入每一项的系数和指数:\n");
for (int i = 0; i < terms; i++) {
printf("第 %d 项:", i + 1);
scanf("%d %d", &coefficient, &exponent);
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->coefficient = coefficient;
newNode->exponent = exponent;
newNode->next = NULL;
if (*poly == NULL) {
*poly = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = tail->next;
}
}
}
// 输出多项式
void displayPolynomial(Node* poly) {
if (poly == NULL) {
printf("多项式为空。\n");
return;
}
while (poly != NULL) {
int coefficient = poly->coefficient;
int exponent = poly->exponent;
if (coefficient != 0) {
if (coefficient > 0) {
printf("+");
}
if (exponent == 0) {
printf("%d ", coefficient);
}
else if (exponent == 1) {
printf("%dx ", coefficient);
}
else {
printf("%dx^%d ", coefficient, exponent);
}
}
poly = poly->next;
}
printf("\n");
}
// 释放多项式的内存
void freePolynomial(Node* poly) {
Node* temp;
while (poly != NULL) {
temp = poly;
poly = poly->next;
free(temp);
}
}
// 多项式相加
Node* addPolynomials(Node* polyA, Node* polyB) {
Node* result = NULL;
Node* tail = NULL;
while (polyA != NULL && polyB != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (polyA->exponent > polyB
->exponent) {
newNode->coefficient = polyA->coefficient;
newNode->exponent = polyA->exponent;
polyA = polyA->next;
}
else if (polyA->exponent < polyB->exponent) {
newNode->coefficient = polyB->coefficient;
newNode->exponent = polyB->exponent;
polyB = polyB->next;
}
else {
newNode->coefficient = polyA->coefficient + polyB->coefficient;
newNode->exponent = polyA->exponent;
polyA = polyA->next;
polyB = polyB->next;
}
newNode->next = NULL;
if (result == NULL) {
result = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = tail->next;
}
}
while (polyA != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->coefficient = polyA->coefficient;
newNode->exponent = polyA->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = tail->next;
polyA = polyA->next;
}
while (polyB != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->coefficient = polyB->coefficient;
newNode->exponent = polyB->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = tail->next;
polyB = polyB->next;
}
result = simplifyPolynomial(result); // 化简多项式
return result;
}
// 多项式相减
Node* subtractPolynomials(Node* polyA, Node* polyB) {
Node* result = NULL;
Node* tail = NULL;
while (polyA != NULL && polyB != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (polyA->exponent > polyB->exponent) {
newNode->coefficient = polyA->coefficient;
newNode->exponent = polyA->exponent;
polyA = polyA->next;
}
else if (polyA->exponent < polyB->exponent) {
newNode->coefficient = -polyB->coefficient; // 注意这里的系数取相反数
newNode->exponent = polyB->exponent;
polyB = polyB->next;
}
else {
newNode->coefficient = polyA->coefficient - polyB->coefficient;
newNode->exponent = polyA->exponent;
polyA = polyA->next;
polyB = polyB->next;
}
newNode->next = NULL;
if (result == NULL) {
result = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = tail->next;
}
}
while (polyA != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->coefficient = polyA->coefficient;
newNode->exponent = polyA->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = tail->next;
polyA = polyA->next;
}
while (polyB != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->coefficient = -polyB->coefficient; // 注意这里的系数取相反数
newNode->exponent = polyB->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = tail->next;
polyB = polyB->next;
}
result = simplifyPolynomial(result); // 化简多项式
return result;
}
// 多项式相乘
Node* multiplyPolynomials(Node* polyA, Node* polyB) {
Node* result = NULL;
Node* tail = NULL;
while (polyA != NULL) {
Node* temp = polyB;
while (temp != NULL) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->coefficient = polyA->coefficient * temp->coefficient;
newNode->exponent = polyA->exponent + temp->exponent;
newNode->next = NULL;
if (result == NULL) {
result = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = tail->next;
}
temp = temp->next;
}
polyA = polyA->next;
}
result = simplifyPolynomial(result); // 化简多项式
return result;
}
// 化简多项式,合并同类项并去除系数为 0 的项
Node* simplifyPolynomial(Node* poly) {
if (poly == NULL) {
return NULL;
}
Node* current = poly;
Node* prev = NULL;
while (current != NULL) {
Node* temp = current->next;
prev = current;
while (temp != NULL) {
if (current->exponent == temp->exponent) {
current->coefficient += temp->coefficient;
// 删除重复项
prev->next = temp->next;
free(temp);
temp = prev->next;
}
else {
prev = temp;
temp = temp->next;
}
}
current = current->next;
}
// 删除系数为 0 的项
current = poly;
prev = NULL;
while (current != NULL) {
if (current->coefficient == 0) {
if (prev == NULL) {
poly = current->next;
free(current);
current = poly;
}
else {
prev->next = current->next;
free(current);
current = prev->next;
}
}
else {
prev = current;
current = current->next;
}
}
return poly;
}
//main.c
#include <stdio.h>
#include <stdlib.h>
#include "poly.h"
int main() {
Node* polyA = NULL;
Node* polyB = NULL;
Node* result = NULL;
int choice;
do {
printf("========= 多项式计算器 =========\n");
printf("1. 输入并建立多项式\n");
printf("2. 输出多项式\n");
printf("3. 多项式相加\n");
printf("4. 多项式相减\n");
printf("5. 多项式相乘\n");
printf("0. 退出\n");
printf("请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("创建多项式 A:\n");
createPolynomial(&polyA);
printf("创建多项式 B:\n");
createPolynomial(&polyB);
break;
case 2:
printf("多项式 A:");
displayPolynomial(polyA);
printf("多项式 B:");
displayPolynomial(polyB);
break;
case 3:
result = addPolynomials(polyA, polyB);
printf("A + B = ");
displayPolynomial(result);
freePolynomial(result);
break;
case 4:
result = subtractPolynomials(polyA, polyB);
printf("A - B = ");
displayPolynomial(result);
freePolynomial(result);
break;
case 5:
result = multiplyPolynomials(polyA, polyB);
printf("A * B = ");
displayPolynomial(result);
freePolynomial(result);
break;
case 0:
printf("退出程序。\n");
break;
default:
printf("无效的选择。\n");
break;
}
printf("\n");
} while (choice != 0);
freePolynomial(polyA);
freePolynomial(polyB);
return 0;
}