Data Structure C Code 2.5: [Linked List] Factorial of 10 & Polynomial Addition Linked List Basic Application Questions

 Think and understand:

Code supplement: There will be a "+" after the teacher's result, which is not beautiful enough. A judgment is added here, and the redundant plus sign after the formula is eliminated. The print prompt has been changed to Chinese for easy viewing.

The ingenuity of the teacher's code: Although only a few test cases are written, the test cases cover all the contents of all methods, and the algorithm is tested by using special values ​​and general values. After the addition, it is judged that no useless items with a coefficient of 0 such as 0*x^n will be left.

learning target:

Learn the linked list and make a topic: the addition of polynomials is the basic application of the linked list, and it is also helpful to understand the compressed representation.

Study Guide: Fanshen's Code

Learning tasks:

  1. copy code
  2. Learning Outcome Catalog

    1 Define the structure

    2 Operation method

    2.1 Initialize polynomial linked list

    2.2 Print polynomial linked list

    2.3 Print an item in the polynomial linked list

    2.4 Added Items by Tail Interpolation

    2.5 Sum of two polynomials

    3 tests

    3.1 Unit Test 1

    3.2 Unit testing 2

    3.3 Test results

    4 all codes

Code description:

1. I spent a lot of time adjusting when writing, so I keep all the adjustment statements. If you don’t like it, you can delete them. 2. It is
difficult to analyze several situations. Especially the addition The final coefficient is 0. Overcoming this obstacle will lead to progress!
Only one linked list is left after the addition, and other useless spaces are released. If you don’t like this method, you can apply for a new space to add, this code will actually be simpler 3.
According to the suggestions of the students, define the return type of main as int, so as to apply to different versions of the compiler.
4. According to the bugs picked by Liu Tao and other students, the test case (with a separate function) is added to two.

5. The general formula of polynomial is       pn(x)=a(n) x^(n) + a(n−1) x^(n−1) +······+a(1)· x+a(0)

                                  Here set x=10

study-time:

2022.5.6

1 Define the structure

/**
 * 创建链表节点结构体
 */
typedef struct LinkNode{
	int coefficient;	//定义系数
	int exponent;		//定义指数
	struct LinkNode *next;
} *LinkList, *NodePtr;

2 Operation method

2.1 Initialize polynomial linked list

/**
 * @brief 初始化链表
 * 
 * @return 头节点
 */
LinkList initLinkList(){
	LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
	tempHeader->coefficient = 0;
	tempHeader->exponent = 0;
	tempHeader->next = NULL;
	return tempHeader;
}

2.2 Print polynomial linked list

/**
 * @brief 打印链表
 * 
 * @param paraHeader 
 */
void printList(LinkList paraHeader){
	NodePtr p = paraHeader->next;
	while (p != NULL&&p->next!=NULL) {
		printf("%d * 10^%d + ", p->coefficient, p->exponent);
		p = p->next;
	}
	if(p!=NULL){
		printf("%d * 10^%d", p->coefficient, p->exponent);
	}
	printf("\n");
}

2.3 Print an item in the polynomial linked list

/**
 * @brief 打印链表其中一个节点
 * 
 * @param paraChar 
 * @param paraPtr 
 */
void printNode(NodePtr paraPtr, char paraChar){
	if (paraPtr == NULL) {
		printf("\t未找到%c多项式节点\n",paraChar);
	} else {
		printf("\t%c多项式的节点是( %d * 10^%d )\n", paraChar, paraPtr->coefficient, paraPtr->exponent);
	}
}

2.4 Added Items by Tail Interpolation

/**
 * @brief 往多项式中添加项
 * 
 * @param paraCoefficient 
 * @param paraExponent 
 * @param paraHeader 
 */
void appendElement(LinkList paraHeader, int paraCoefficient, int paraExponent){
	NodePtr p, q;
	
	//1申请节点空间
	q = (NodePtr)malloc(sizeof(struct LinkNode));
	q->coefficient = paraCoefficient;
	q->exponent = paraExponent;
	q->next = NULL;
	
	//2尾插法,找到链表尾部
	p = paraHeader;
	while (p->next != NULL) {
		p = p->next;
	}
	
	//3连接
	p->next = q;
}

2.5 Sum of two polynomials

/**
 * @brief 将多项式进行相加
 * 
 * @param paraList1 
 * @param paraList2 
 */
void add(NodePtr paraList1, NodePtr paraList2){
	NodePtr p, q, r, s;
	
	//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("情况1:链表r的指数较小\n");
			r->next = p;
			r = p;
			printNode(r, 'r');
			p = p->next;
			printNode(p, 'p');
		} else if ((p->exponent > q->exponent)) {
			printf("情况2:链表r的指数较大\n");
			r->next = q;
			r = q;
			printNode(r, 'r');
			q = q->next;
			printNode(q, 'q');
		} else {
			printf("情况3:链表指数相等\n");
			p->coefficient = p->coefficient + q->coefficient;
			if (p->coefficient == 0) {
				printf("\t3.1系数和为0,删去该多项式节点\n");
				s = p;
				p = p->next;
				printNode(p, 'p');
			} else {
				printf("\t3.2系数和为%d,相加成功\n",p->coefficient);
				r = p;
				printNode(r, 'r');
				p = p->next;
				printNode(p, 'p');
			}
			s = q;
			q = q->next;
			free(s);
		}
		
		printf("\tp的地址为%ld, q的地址为%ld \n", p, q);
	}
	
	
	if (p == NULL) {
		r->next = q;
	} else {
		r->next = p;
	}
	
	printf("****两多项式相加成功****\r\n");
}

3 tests

3.1 Unit Test 1

/**
 * 单元测试1
 */
void additionTest1(){
	printf("----单元测试1开始测试-----\n");
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printf("第一个多项式为:   ");
	printList(tempList1);

	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 8);
	printf("第二个多项式为:   ");
	printList(tempList2);
			printf("\n****多项式相加的过程****\n");
	
	add(tempList1, tempList2);
	printf("\n相加后结果是: ");
	printList(tempList1);
	printf("\n---- 单元测试1结束 ----\n\n");
}

3.2 Unit testing 2

/**
 * 单元测试2
 */
void additionTest2(){
printf("----单元测试2开始测试-----\n");
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printf("第一个多项式为:   ");
	printList(tempList1);
	
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 10);
	printf("第二个多项式为:   ");
	printList(tempList2);
		printf("\n****多项式相加的过程****\n");
	
	add(tempList1, tempList2);
	printf("\n相加后结果是: ");
	printList(tempList1);
	printf("\n---- 单元测试2结束 ----\n");
}

3.3 Test results

----单元测试1开始测试-----
第一个多项式为:   7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17
第二个多项式为:   8 * 10^1 + 22 * 10^7 + -9 * 10^8

****多项式相加的过程****
        p多项式的节点是( 7 * 10^0 )
        q多项式的节点是( 8 * 10^1 )
        r多项式的节点是( 0 * 10^0 )
情况1:链表r的指数较小
        r多项式的节点是( 7 * 10^0 )
        p多项式的节点是( 3 * 10^1 )
        p的地址为-1026746528, q的地址为-1026746400
情况3:链表指数相等
        3.2系数和为11,相加成功
        r多项式的节点是( 11 * 10^1 )
        p多项式的节点是( 9 * 10^8 )
        p的地址为-1026746496, q的地址为-1026746368
情况2:链表r的指数较大
        r多项式的节点是( 22 * 10^7 )
        q多项式的节点是( -9 * 10^8 )
        p的地址为-1026746496, q的地址为-1026746336
情况3:链表指数相等
        3.1系数和为0,删去该多项式节点
        p多项式的节点是( 5 * 10^17 )
        p的地址为-1026746464, q的地址为0
****两多项式相加成功****

相加后结果是: 7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 5 * 10^17

---- 单元测试1结束 ----

----单元测试2开始测试-----
第一个多项式为:   7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17
第二个多项式为:   8 * 10^1 + 22 * 10^7 + -9 * 10^10

****多项式相加的过程****
        p多项式的节点是( 7 * 10^0 )
        q多项式的节点是( 8 * 10^1 )
        r多项式的节点是( 0 * 10^0 )
情况1:链表r的指数较小
        r多项式的节点是( 7 * 10^0 )
        p多项式的节点是( 3 * 10^1 )
        p的地址为-1026746336, q的地址为-1026746208
情况3:链表指数相等
        3.2系数和为11,相加成功
        r多项式的节点是( 11 * 10^1 )
        p多项式的节点是( 9 * 10^8 )
        p的地址为-1026746304, q的地址为-1026746176
情况2:链表r的指数较大
        r多项式的节点是( 22 * 10^7 )
        q多项式的节点是( -9 * 10^10 )
        p的地址为-1026746304, q的地址为-1026646144
情况1:链表r的指数较小
        r多项式的节点是( 9 * 10^8 )
        p多项式的节点是( 5 * 10^17 )
        p的地址为-1026746272, q的地址为-1026646144
情况2:链表r的指数较大
        r多项式的节点是( -9 * 10^10 )
        未找到q多项式节点
        p的地址为-1026746272, q的地址为0
****两多项式相加成功****

相加后结果是: 7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 9 * 10^8 + -9 * 10^10 + 5 * 10^17

---- 单元测试2结束 ----

--------------------------------
Process exited after 0.07614 seconds with return value 0

Press ANY key to continue...

4 all codes

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

/**
 * 创建链表节点结构体
 */
typedef struct LinkNode{
	int coefficient;	//定义系数
	int exponent;		//定义指数
	struct LinkNode *next;
} *LinkList, *NodePtr;

/**
 * @brief 初始化链表
 * 
 * @return 头节点
 */
LinkList initLinkList(){
	LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
	tempHeader->coefficient = 0;
	tempHeader->exponent = 0;
	tempHeader->next = NULL;
	return tempHeader;
}

/**
 * @brief 打印链表
 * 
 * @param paraHeader 
 */
void printList(LinkList paraHeader){
	NodePtr p = paraHeader->next;
	while (p != NULL&&p->next!=NULL) {
		printf("%d * 10^%d + ", p->coefficient, p->exponent);
		p = p->next;
	}
	if(p!=NULL){
		printf("%d * 10^%d", p->coefficient, p->exponent);
	}
	printf("\n");
}
/**
 * @brief 打印链表其中一个节点
 * 
 * @param paraChar 
 * @param paraPtr 
 */
void printNode(NodePtr paraPtr, char paraChar){
	if (paraPtr == NULL) {
		printf("\t未找到%c多项式节点\n",paraChar);
	} else {
		printf("\t%c多项式的节点是( %d * 10^%d )\n", paraChar, paraPtr->coefficient, paraPtr->exponent);
	}
}

/**
 * @brief 往多项式中添加项
 * 
 * @param paraCoefficient 
 * @param paraExponent 
 * @param paraHeader 
 */
void appendElement(LinkList paraHeader, int paraCoefficient, int paraExponent){
	NodePtr p, q;
	
	//1申请节点空间
	q = (NodePtr)malloc(sizeof(struct LinkNode));
	q->coefficient = paraCoefficient;
	q->exponent = paraExponent;
	q->next = NULL;
	
	//2尾插法,找到链表尾部
	p = paraHeader;
	while (p->next != NULL) {
		p = p->next;
	}
	
	//3连接
	p->next = q;
}

/**
 * @brief 将多项式进行相加
 * 
 * @param paraList1 
 * @param paraList2 
 */
void add(NodePtr paraList1, NodePtr paraList2){
	NodePtr p, q, r, s;
	
	//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("情况1:链表r的指数较小\n");
			r->next = p;
			r = p;
			printNode(r, 'r');
			p = p->next;
			printNode(p, 'p');
		} else if ((p->exponent > q->exponent)) {
			printf("情况2:链表r的指数较大\n");
			r->next = q;
			r = q;
			printNode(r, 'r');
			q = q->next;
			printNode(q, 'q');
		} else {
			printf("情况3:链表指数相等\n");
			p->coefficient = p->coefficient + q->coefficient;
			if (p->coefficient == 0) {
				printf("\t3.1系数和为0,删去该多项式节点\n");
				s = p;
				p = p->next;
				printNode(p, 'p');
			} else {
				printf("\t3.2系数和为%d,相加成功\n",p->coefficient);
				r = p;
				printNode(r, 'r');
				p = p->next;
				printNode(p, 'p');
			}
			s = q;
			q = q->next;
			free(s);
		}
		
		printf("\tp的地址为%ld, q的地址为%ld \n", p, q);
	}
	
	
	if (p == NULL) {
		r->next = q;
	} else {
		r->next = p;
	}
	
	printf("****两多项式相加成功****\r\n");
}

/**
 * 单元测试1
 */
void additionTest1(){
	printf("----单元测试1开始测试-----\n");
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printf("第一个多项式为:   ");
	printList(tempList1);

	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 8);
	printf("第二个多项式为:   ");
	printList(tempList2);
			printf("\n****多项式相加的过程****\n");
	
	add(tempList1, tempList2);
	printf("\n相加后结果是: ");
	printList(tempList1);
	printf("\n---- 单元测试1结束 ----\n\n");
}

/**
 * 单元测试2
 */
void additionTest2(){
printf("----单元测试2开始测试-----\n");
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printf("第一个多项式为:   ");
	printList(tempList1);
	
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 10);
	printf("第二个多项式为:   ");
	printList(tempList2);
		printf("\n****多项式相加的过程****\n");
	
	add(tempList1, tempList2);
	printf("\n相加后结果是: ");
	printList(tempList1);
	printf("\n---- 单元测试2结束 ----\n");
}

int main(){
	additionTest1();
	additionTest2();
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_61649579/article/details/124611126