数据结构 – 多项式加法

简介

此模块为学校数据结构必修课学习内容的记录与分享

全文大体分为一下几个部分

  • 前言
  • 背景
  • 分析(伪代码部分)
  • 代码
  • 结果
  • Points

前言

由于前段时间赶团队培训进度,后面需要对培训内容进行总结,因此以后相当一部分时间在 homework 上面的时间可能会减少,因此先贴出主要思路及要点,后面抽时间进行细节补充与整理

又挖坑了…QAQ

背景

多项式加法是基于链表数据结构的基础实际运用

本例选用一般化的稀疏多项式,考验对特殊特殊情况的处理

实现的基本目标如下:(需求分析)

输入两个稀疏多项式,输出其相加结果

eg:

// 输入:
7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17
8 * 10^1 + 22 * 10^7 + -9 * 10^8
// 输出:
7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 9 * 10^8 + -9 * 10^10 + 5 * 10^17

分析

需要创建结构体储存:

  1. 系数信息
  2. 次方信息
  3. 下一个节点地址

因此大概的结构体内容就出来了:

typedef struct LinkNode {
    int coefficient;        // 系数
    int exponent;           // 幂
    NodePtr next;
    struct LinkNode *next;  // 指向下一个节点的指针
}*LinkList,*NodePtr;

这里注意一个点:

不能用该结构体的别名在其内部创建变量

因为编译器是自上而下编译代码的,对于这里创建的结构体,编译器首先会自上而下识别结构体的内容,再为其创建别名,如果直接用该结构体的别名在其内部创建变量会报错变量未识别。

指针移动

一图简示:

首先需要确定哪一个链表作为更新的新链表

然后进行一般化的判断:

  1. 链表尾部是否为空【是则将非空后的节点链接到新链表尾部】
  2. 节点幂次比较【p大则插入节点、p小则p节点移动】
  3. 节点合并计算【注意求和后结果为0的特殊情况】

代码

这里先贴上课堂代码,后面进行补充

#include <stdio.h>
#include <malloc.h>

typedef struct LinkNode{
	int coefficient;
	int exponent;
	struct LinkNode *next;
} *LinkList, *NodePtr;

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;

        // 创建一个新节点并赋值
	// Step 1. Construct a new node.
	q = (NodePtr)malloc(sizeof(struct LinkNode));
	q->coefficient = paraCoefficient;
	q->exponent = paraExponent;
	q->next = NULL;
        
        // 找到插入的位置
	// Step 2. Search to the tail.
	p = paraHeader;
	while (p->next != NULL) {
		p = p->next;
	}
        
        // 添加节点
	// Step 3. Now add/link.
	p->next = q;
}

// 多项式加法函数
void add(NodePtr paraList1, NodePtr paraList2){
	NodePtr p, q, r, s;
        
        // 指针准备
        // 选取List1作为更新链表
        // 指针指向后直接free List2
	// Step 1. Search to the position.
	p = paraList1->next;
	printNode(p, 'p');
	q = paraList2->next;
	printNode(q, 'q');
	r = paraList1; // Previous pointer for inserting.
	printNode(r, 'r');
	free(paraList2); // The second list is destroyed. 
	
        // 第一个判断条件 - 是否NULL
	while ((p != NULL) && (q != NULL)) {
                // 小于部分,p指针++
		if (p->exponent < q->exponent) {
			//Link the current node of the first list.
			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)) {  // 大于部分,进行节点的插入
			//Link the current node of the second list.
			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");
			//Change the current node of the first list.
			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

/**
 * Unit test 1.
 */
void additionTest1(){
	// Step 1. Initialize the first polynomial.
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printList(tempList1);

	// Step 2. Initialize the second polynomial.
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 8);
	printList(tempList2);

	// Step 3. Add them to the first.
	add(tempList1, tempList2);
	printf("The result is: ");
	printList(tempList1);
	printf("\r\n");
}// Of additionTest1

/**
 * Unit test 2.
 */
void additionTest2(){
	// Step 1. Initialize the first polynomial.
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printList(tempList1);

	// Step 2. Initialize the second polynomial.
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 10);
	printList(tempList2);

	// Step 3. Add them to the first.
	add(tempList1, tempList2);
	printf("The result is: ");
	printList(tempList1);
	printf("\r\n");
}// Of additionTest2

/**
 * The entrance.
 */
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
2025年4月14日 创建

评论

  1. quanjun
    Windows Edge
    6 天前
    2025-4-22 9:02:15

    666666

  2. mayun
    Windows Edge
    6 天前
    2025-4-22 9:02:47

    hello

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
Copyright 2025-2025 @ Ziyang
Running Time days H M S