Data Structures C Code 2.5: Addition of Polynomials

Abstract : The addition of polynomials is a fundamental application of linked lists and also helps to understand compressed representations.

1. Code (version 2022)

Code first, then nonsense.

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

/**
 * Linked list of integers. The key is data. The key is sorted in non-descending order.
 */
typedef struct LinkNode{
	int coefficient;
	int exponent;
	struct LinkNode *next;
} *LinkList, *NodePtr;

/**
 * Initialize the list with a header.
 * @return The pointer to the header.
 */
LinkList initLinkList(){
	LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
	tempHeader->coefficient = 0;
	tempHeader->exponent = 0;
	tempHeader->next = NULL;
	return tempHeader;
}// Of initLinkList

/**
 * Print the list.
 * @param paraHeader The header of the list.
 */
void printList(LinkList paraHeader){
	NodePtr p = paraHeader->next;
	while (p != NULL) {
		printf("%d * 10^%d + ", p->coefficient, p->exponent);
		p = p->next;
	}// Of while
	printf("\r\n");
}// Of printList

/**
 * Print one node for testing.
 * @param paraPtr The pointer to the node.
 * @param paraChar The name of the node.
 */
void printNode(NodePtr paraPtr, char paraChar){
	if (paraPtr == NULL) {
		printf("NULL\r\n");
	} else {
		printf("The element of %c is (%d * 10^%d)\r\n", paraChar, paraPtr->coefficient, paraPtr->exponent);
	}// Of while
}// Of printNode

/**
 * Add an element to the tail.
 * @param paraCoefficient The coefficient of the new element.
 * @param paraExponent The exponent of the new element.
 */
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;
	}// Of while

	// Step 3. Now add/link.
	p->next = q;
}// Of appendElement

/**
 * Polynomial addition.
 * @param paraList1 The first list.
 * @param paraList2 The second list.
 */
void add(NodePtr paraList1, NodePtr paraList2){
	NodePtr p, q, r, s;

	// 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. 
	
	while ((p != NULL) && (q != NULL)) {
		if (p->exponent < q->exponent) {
			//Link the current node of the first list.
			printf("case 1\r\n");
			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 = %ld, q = %ld \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.
 */
void additionTest(){
	// 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);
	printList(tempList1);
}// Of additionTest

/**
 * The entrance.
 */
void main(){
	additionTest();
	printf("Finish.\r\n");
}// Of main

2. Running results

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 = 5652160, q = 5652384
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 = 5652216, q = 5641768
case 2
The element of r is (22 * 10^7)
The element of q is (-9 * 10^8)
p = 5652216, q = 5641824
case 3
The coefficient is: 0.
case 3.1
The element of p is (5 * 10^17)
p = 5652272, q = 0
End of while.
Addition ends.
7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 5 * 10^17 +
Finish.
Press any key to continue

3. Code Description

  1. I spent a lot of time swiping while writing, so keep all the swipe statements. If you don't like them, you can delete them.
  2. It is difficult to analyze several situations. Especially after the addition, the coefficient is 0. If you cross this obstacle, you will be advanced!
  3. After the addition, there is only one linked list left, and other useless spaces are released. If you don't like this method, you can apply for a new space for addition, and the code will be simpler.

Guess you like

Origin blog.csdn.net/minfanphd/article/details/124447526