数据结构作业5--多项式的加法

本文详细介绍了使用链表结构实现多项式加法的C语言代码,包括链表的创建、节点操作、多项式元素的添加以及加法过程中的比较和合并策略。通过实例展示了如何在链表中按非降序存储并执行加法运算。
摘要由CSDN通过智能技术生成

摘要多项式的加法是链表的基本应用, 也有助于理解压缩表示.

代码本体
#include <stdio.h>
#include <malloc.h>

/**
 * 整数链表. 主体内容为data.按非降序排序.
 */
typedef struct LinkNode{
	int coefficient;
	int exponent;
	struct LinkNode *next;
} *LinkList, *NodePtr;

/**
 *  用头文件初始化链表.
 * @return 指向头结点的指针.
 */
LinkList initLinkList(){
	LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
	tempHeader->coefficient = 0;
	tempHeader->exponent = 0;
	tempHeader->next = NULL;
	return tempHeader;
}// Of initLinkList

/**
 * 打印链表.
 * @param paraHeader 链表的头结点.
 */
void printList(LinkList paraHeader){
	NodePtr p = paraHeader->next;
	while (p != NULL) {
		printf("%d * x^%d + ", p->coefficient, p->exponent);
		p = p->next;
	}// Of while
	printf("\r\n");
}// Of printList

/**
 * 打印一个节点用于测试.
 * @param paraPtr 指向节点的指针.
 * @param paraChar 节点的名称.
 */
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);
	}// Of while
}// Of printNode

/**
 * 在尾部添加一个元素.
 * @param paraCoefficient 新元素的系数.
 * @param paraExponent 新元素的指数.
 */
void appendElement(LinkList paraHeader, int paraCoefficient, int paraExponent){
	NodePtr p, q;

	// Step 1. 构建一个新节点.
	q = (NodePtr)malloc(sizeof(struct LinkNode));
	q->coefficient = paraCoefficient;
	q->exponent = paraExponent;
	q->next = NULL;

	// Step 2. 搜索到尾部.
	p = paraHeader;
	while (p->next != NULL) {
		p = p->next;
	}// Of while

	// Step 3. 添加/链接.
	p->next = q;
}// Of appendElement

/**
 * 多项式加法.
 * @param paraList1 第一个链表.
 * @param paraList2 第二个链表.
 */
void add(NodePtr paraList1, NodePtr paraList2){
	NodePtr p, q, r, s;

	// Step 1. 搜索到地址.
	p = paraList1->next;
	printNode(p, 'p');
	q = paraList2->next;
	printNode(q, 'q');
	r = paraList1; // 插入的前一个指针.
	printNode(r, 'r');
	free(paraList2); // 第二个链表被销毁. 
	
	while ((p != NULL) && (q != NULL)) {
		if (p->exponent < q->exponent) {
			//链接第一个链表的当前节点.
			printf("case 1\r\n");
			r->next = p;
			r = p;
			printNode(r, 'r');
			p = p->next;
			printNode(p, 'p');
		} else if ((p->exponent > q->exponent)) {
			//链接第二个链表的当前节点.
			printf("case 2\r\n");
			r->next = q;
			r = q;
			printNode(r, 'r');
			q = q->next;
			printNode(q, 'q');
		} else {
			printf("case 3\r\n");
			//改变第一个链表的当前节点.
			p->coefficient = p->coefficient + q->coefficient;
			printf("The coefficient is: %d.\r\n", p->coefficient);
			if (p->coefficient == 0) {
				printf("case 3.1\r\n");
				s = p;
				p = p->next;
				printNode(p, 'p');
				// free(s);
			} else {
				printf("case 3.2\r\n");
				r = p;
				printNode(r, 'r');
				p = p->next;
				printNode(p, 'p');
			}// Of if
			s = q;
			q = q->next;
			//printf("q is pointing to (%d, %d)\r\n", q->coefficient, q->exponent);
			free(s);
		}// Of if

		printf("p = %p, q = %p\r\n", p, q);
	} // Of while
	printf("End of while.\r\n");

	if (p == NULL) {
		r->next = q;
	} else {
		r->next = p;
	} // Of if

	printf("Addition ends.\r\n");
}// Of add

/**
 * 测试 1.
 */
void additionTest1(){
	// Step 1. 初始化第一个多项式.
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printList(tempList1);

	// Step 2. 初始化第二个多项式.
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 8);
	printList(tempList2);

	// Step 3. 把他们添加到第一个.
	add(tempList1, tempList2);
	printf("The result is: ");
	printList(tempList1);
	printf("\r\n");
}// Of additionTest1

/**
 * 测试 2.
 */
void additionTest2(){
	// Step 1. 初始化第一个多项式.
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printList(tempList1);

	// Step 2. 初始化第二个多项式.
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 10);
	printList(tempList2);

	// Step 3. 把他们添加到第一个.
	add(tempList1, tempList2);
	printf("The result is: ");
	printList(tempList1);
	printf("\r\n");
}// Of additionTest2

/**
 * 入口
 */
int main(){
	additionTest1();
	additionTest2();
	printf("Finish.\r\n");
	return 0;
}// Of main

运行结果
7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17 +
8 * 10^1 + 22 * 10^7 + -9 * 10^8 +
The element of p is (7 * 10^0)
The element of q is (8 * 10^1)
The element of r is (0 * 10^0)
case 1
The element of r is (7 * 10^0)
The element of p is (3 * 10^1)
p = 9977536, q = 9977760
case 3
The coefficient is: 11.
case 3.2
The element of r is (11 * 10^1)
The element of p is (9 * 10^8)
p = 9977592, q = 9967144
case 2
The element of r is (22 * 10^7)
The element of q is (-9 * 10^8)
p = 9977592, q = 9967200
case 3
The coefficient is: 0.
case 3.1
The element of p is (5 * 10^17)
p = 9977648, q = 0
End of while.
Addition ends.
The result is: 7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 5 * 10^17 +

7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17 +
8 * 10^1 + 22 * 10^7 + -9 * 10^10 +
The element of p is (7 * 10^0)
The element of q is (8 * 10^1)
The element of r is (0 * 10^0)
case 1
The element of r is (7 * 10^0)
The element of p is (3 * 10^1)
p = 9967200, q = 9967424
case 3
The coefficient is: 11.
case 3.2
The element of r is (11 * 10^1)
The element of p is (9 * 10^8)
p = 9967256, q = 9967480
case 2
The element of r is (22 * 10^7)
The element of q is (-9 * 10^10)
p = 9967256, q = 9977816
case 1
The element of r is (9 * 10^8)
The element of p is (5 * 10^17)
p = 9967312, q = 9977816
case 2
The element of r is (-9 * 10^10)
NULL
p = 9967312, q = 0
End of while.
Addition ends.
The result is: 7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 9 * 10^8 + -9 * 10^10 + 5 * 10^17 +

Finish.
Press any key to continue

代码说明
  1. 我在写的时候都用了不少时间调拭, 所以将所有的调拭语句保留. 如果不喜欢, 可以将它们删除.
  2. 对几种情况的分析有一定难度. 特别是相加后系数为 0. 跨越这个障碍就会进阶!
  3. 相加后仅剩一个链表, 其它无用空间都被释放. 如果不喜欢这种方式, 可以申请新空间进行相加, 这样的代码其实会更简单.
  4. 根据同学们的建议将 main 的返回类型定义为 int, 以适用不同版本的编译器.
  5. 根据刘涛等同学挑的 bug 进行了修改, 并且把测试用例 (用单独的函数) 增加到两个.
图示

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值