数据结构第五次作业(多项式相加、栈)
多项式相加
代码
#include <stdio.h>
#include <stdlib.h>
// 定义一个链表节点,用于表示多项式的单项式,包含系数和指数
typedef struct LinkNode {
int coefficient; // 系数
int exponent; // 指数
struct LinkNode *next; // 指向下一个节点的指针
} *LinkList, *NodePtr;
// 初始化一个带头节点的链表,头节点的系数和指数都是0,返回链表头节点指针
LinkList initLinkList() {
LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
tempHeader->coefficient = 0;
tempHeader->exponent = 0;
tempHeader->next = NULL;
return tempHeader;
}
// 打印链表,遍历链表每个节点,打印节点中的系数和指数
void printList(LinkList paraHeader) {
NodePtr p = paraHeader->next;
while (p != NULL) {
printf("%d * x^%d + ", p->coefficient, p->exponent);
p = p->next;
}
printf("\r\n");
}
// 打印单个节点的信息,用于测试
void printNode(NodePtr paraPtr, char paraChar) {
if (paraPtr == NULL) {
printf("NULL\r\n");
} else {
printf("The element of %c is (%d * x^%d)\r\n", paraChar, paraPtr->coefficient, paraPtr->exponent);
}
}
// 在链表尾部添加一个新的节点,新节点包含系数和指数信息
void appendElement(LinkList paraHeader, int paraCoefficient, int paraExponent) {
NodePtr p, q;
// 创建一个新节点
q = (NodePtr)malloc(sizeof(struct LinkNode));
q->coefficient = paraCoefficient;
q->exponent = paraExponent;
q->next = NULL;
// 找到链表的尾部
p = paraHeader;
while (p->next != NULL) {
p = p->next;
}
// 将新节点添加到链表尾部
p->next = q;
}
// 多项式相加,将两个多项式相加的结果存储在第一个多项式中
void add(NodePtr paraList1, NodePtr paraList2) {
NodePtr p, q, r, s;
// 初始化指针,p和q分别指向两个链表的第一个节点
p = paraList1->next;
printNode(p, 'p');
q = paraList2->next;
printNode(q, 'q');
r = paraList1; // r用于追踪结果链表的最后一个节点
printNode(r, 'r');
free(paraList2); // 释放第二个链表的头节点
// 合并两个链表
while ((p != NULL) && (q != NULL)) {
if (p->exponent < q->exponent) {
// 第一个链表的当前节点的指数更小,直接链接到结果链表
r->next = p;
r = p;
p = p->next;
} else if (p->exponent > q->exponent) {
// 第二个链表的当前节点的指数更小,链接到结果链表
r->next = q;
r = q;
q = q->next;
} else {
// 两个链表的当前节点指数相同,合并节点
p->coefficient += q->coefficient;
if (p->coefficient == 0) {
// 如果合并后系数为0,移除这个节点
s = p;
p = p->next;
} else {
// 如果系数不为0,链接到结果链表
r = p;
p = p->next;
}
s = q;
q = q->next;
free(s);
}
}
// 将剩余的节点链接到结果链表
if (p == NULL) {
r->next = q;
} else {
r->next = p;
}
}
// 单元测试1:测试多项式相加的功能
void additionTest1() {
LinkList tempList1 = initLinkList();
appendElement(tempList1, 7, 0);
appendElement(tempList1, 3, 1);
appendElement(tempList1, 9, 8);
appendElement(tempList1, 5, 17);
printList(tempList1);
LinkList tempList2 = initLinkList();
appendElement(tempList2, 8, 1);
appendElement(tempList2, 22, 7);
appendElement(tempList2, -9, 8);
printList(tempList2);
add(tempList1, tempList2);
printf("The result is: ");
printList(tempList1);
printf("\r\n");
}
// 单元测试2:测试多项式相加的功能
void additionTest2() {
LinkList tempList1 = initLinkList();
appendElement(tempList1, 7, 0);
appendElement(tempList1, 3, 1);
appendElement(tempList1, 9, 8);
appendElement(tempList1, 5, 17);
printList(tempList1);
LinkList tempList2 = initLinkList();
appendElement(tempList2, 8, 1);
appendElement(tempList2, 22, 7);
appendElement(tempList2, -9, 10);
printList(tempList2);
add(tempList1, tempList2);
printf("The result is: ");
printList(tempList1);
printf("\r\n");
}
// main函数,程序入口
int main() {
additionTest1();
additionTest2();
printf("Finish.\r\n");
return 0;
}
代码总结:
- 这段代码实现了一个链表结构,用来表示多项式。每个节点包含一个系数(
coefficient
)和一个指数(exponent
),以及一个指向下一个节点的指针(next
)。 - 提供了初始化链表、打印链表、在链表末尾添加元素和多项式相加的功能。
initLinkList
函数创建一个空的链表,即带有一个头节点的链表。printList
函数遍历链表并打印每个节点的系数和指数。appendElement
函数在链表的末尾添加一个新的节点。add
函数将两个链表表示的多项式相加,并将结果存储在第一个链表中。如果两个多项式中有相同指数的项,则将这些项的系数相加;如果相加后系数为0,则该项被移除。第二个链表在相加过程中被销毁。additionTest1
和additionTest2
两个函数是单元测试,用于测试多项式相加的功能。main
函数作为程序的入口,调用了两个测试函数,并在最后打印了“Finish.”表示程序结束。
运行结果
栈
代码
#include <stdio.h>
#include <stdlib.h>
#define STACK_MAX_SIZE 10 // 定义栈的最大容量
// 定义一个字符栈的结构体
typedef struct CharStack {
int top; // 栈顶指针,初始化为-1,表示栈为空
int data[STACK_MAX_SIZE]; // 栈的存储数组,最大长度固定
} *CharStackPtr;
// 输出栈中的元素
void outputStack(CharStackPtr paraStack) {
for (int i = 0; i <= paraStack->top; i ++) {
printf("%c ", paraStack->data[i]);
}
printf("\r\n");
}
// 初始化一个空的字符栈
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1; // 初始化栈顶指针为-1
return resultPtr;
}
// 向栈中推入一个元素
void push(CharStackPtr paraStackPtr, int paraValue) {
if (paraStackPtr->top >= STACK_MAX_SIZE - 1) { // 检查栈空间是否已满
printf("Cannot push element: stack full.\r\n");
return;
}
paraStackPtr->top++; // 更新栈顶指针
paraStackPtr->data[paraStackPtr->top] = paraValue; // 将元素推入栈中
}
// 从栈中弹出一个元素
char pop(CharStackPtr paraStackPtr) {
if (paraStackPtr->top < 0) { // 检查栈是否为空
printf("Cannot pop element: stack empty.\r\n");
return '\0'; // 如果栈为空,返回空字符
}
paraStackPtr->top--; // 更新栈顶指针
return paraStackPtr->data[paraStackPtr->top + 1]; // 返回弹出的元素
}
// 测试push和pop函数
void pushPopTest() {
printf("---- pushPopTest begins. ----\r\n");
CharStackPtr tempStack = charStackInit(); // 初始化栈
printf("After initialization, the stack is: ");
outputStack(tempStack);
// 推入元素
for (char ch = 'a'; ch < 'm'; ch ++) {
printf("Pushing %c.\r\n", ch);
push(tempStack, ch);
outputStack(tempStack);
}
// 弹出元素
char ch;
for (int i = 0; i < 3; i ++) {
ch = pop(tempStack);
printf("Pop %c.\r\n", ch);
outputStack(tempStack);
}
printf("---- pushPopTest ends. ----\r\n");
}
// 程序入口点
int main() {
pushPopTest(); // 运行测试函数
}
代码总结:
-
定义了一个固定大小的栈(
STACK_MAX_SIZE
为10),用于存储字符。 -
CharStack
结构体包含一个栈顶指针top
和一个数据数组data
。栈顶指针初始化为-1,表示栈为空。 -
charStackInit
函数用于初始化一个空栈,并返回栈的指针。 -
push
函数用于向栈中推入一个新元素。它首先检查栈是否已满,如果未满,则将新元素推入栈顶。 -
pop
函数用于从栈中弹出一个元素。它首先检查栈是否为空,如果不为空,则弹出栈顶元素并返回。 -
outputStack
函数用于输出栈中的所有元素。 -
pushPopTest
函数是一个测试函数,用于测试push
和pop
操作。它首先初始化一个栈,然后连续推入一系列字符,之后弹出几个字符,每次操作后都输出栈的当前状态。 -
main
函数是程序的入口点,它调用pushPopTest
函数来执行测试。