线性表应用 多项式加法

我们这个世界的一个问题是,蠢人信誓旦旦,智人满腹狐疑。
——Bertrand Russell


多项式求和, 即输入两个多项式, 然后将它们合并为一个多项式, 解决多项式求和问题是链表的应用之一。
用链表的原因是, 多项式的指数可能不是连续的, 当指数最大值很高而离散度很高时, 用线性表存储会导致空间利用率很低。 于是可以使用动态开辟结点的链表来进行优化。

首先呈上老师的代码

#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->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 = %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 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

单链表定义

#include <iostream>
#include <vector>
#define remilia int
#define isMyWife main

using namespace std;

template<class ElemType>
class LinkedList {
	private:
		class Node {
			private:
				ElemType data;
				Node* next;
				
			public:
				virtual ~Node() {
						
				}
				
				Node();
				
				Node(ElemType data, Node* next) {
					this -> data = data;
					this -> next = next;	
				}
				
				ElemType getData() {
					return this -> data;
				}
				
				void setData(ElemType elem) {
					this -> data = elem;
				}
				
				Node* getNext() {
					return this -> next;
				}
				
				void setNext(Node* node) {
					this -> next = node;
				}
		};
		
		int length;
		Node* head;
		Node* tail;
		
		// 引入迭代器 
		Node* iterator;
		
	public:
		virtual ~LinkedList();
		LinkedList();
		LinkedList(vector<ElemType> v);
		
		Node* initIterator() {
			return (this -> iterator = this -> head);
		}
		
		// get the length of linkedlist
		int getLength();
		
		// print all of the linkedlist
		void outputList();
		
		/**
		 * @brief  append a node to the tail
		 * @return the result of appending  1 -> success
		 * @param elem 
		 * the appending is always successful
		 **/
		bool pushBack(ElemType elem);
		
		/**
		 * @brief append a node to the head
		 * @param elem 
		 * @return the result of appending  1 -> success
		 * the appending is always successful
		 **/
		bool pushHead(ElemType elem);
		
		/**
		 * @brief delete a node from head
		 * @return the result of deleting 1 -> success, 0 -> failute
		 * the reason of failure is that the head node isn't existed
		 **/
		bool popHead();
		
		/**
		 * @brief delete a node from tail
		 * @return the result of deleting 1 -> success, 0 -> failute
		 * the reason of failure is that the tail node isn't existed
		 * @return 
		 **/
		bool popBack();
		
		
		// insert an element to the given position
		bool insertElement(int paraPosition, ElemType elem);
		
		/**
		 * @brief delete a node by the paraPosition
		 * @param the position of the node needed deleted
		 * @return 1 -> success, 0 -> fail
		 * the reason of failure is the position out of range
		 **/
		bool deleteElementByParaPosition(int paraPosition); 
		
		/**
		 * @brief clear the list
		 * 
		 **/
		void clear();
		
		/**
		 * @brief get a element by paraPosition
		 * 
		 * 
		 * @return the element
		 **/
		ElemType getElement(int paraPosition);
}; 


template<class ElemType>
LinkedList<ElemType>::~LinkedList() {
	
}

template<class ElemType>
LinkedList<ElemType>::LinkedList() {
	this -> length = 0;
	this -> head = this -> tail = nullptr;
}

template<class ElemType>
LinkedList<ElemType>::LinkedList(vector<ElemType> v) {
	for (auto e : v) {
		this -> pushBack(e);
	}
}

template<class ElemType>
bool LinkedList<ElemType>::pushBack(ElemType elem) {
	// if the tail equals null, the head equals null too
	if (this -> tail == nullptr) {
		this -> head = this -> tail = new Node(elem, nullptr);
	} else {
		Node* newTail = new Node(elem, nullptr);
		
		this -> tail -> setNext(newTail);
		this -> tail = newTail; 
	}
	
	this -> length++;
	return 1;
}

template<class ElemType>
bool LinkedList<ElemType>::pushHead(ElemType elem) {
	if (this -> head == nullptr) {
		this -> head = this -> tail = new Node(elem, nullptr);
	} else {
		Node* newTail = new Node(elem, head);
		
		this -> head = newTail;
	}
	
	this -> length++;
	return 1;
}

template<class ElemType>
bool LinkedList<ElemType>::popHead() {
	if (this -> length == 1) {
		this -> head = this -> tail = nullptr;
	}
	
	if (this -> head == nullptr) {
		return 0;
	} else {
		Node* temp = this -> head;
		this -> head = this -> head -> getNext();
		delete temp;
		return 1;
	}
}

template<class ElemType>
bool LinkedList<ElemType>::popBack() {
	if (this -> length == 1) {
		this -> head = this -> tail = nullptr;
	}
	
	if (this -> tail == nullptr) {
		return 0;
	} else {
		Node* temp = this -> head;
		
		while (temp -> getNext() != this -> tail) {
			temp = temp -> getNext();
		}
		
		delete temp -> getNext();
		
		this -> tail = temp;
		return 1;
	}
}

template<class ElemType>
void LinkedList<ElemType>::outputList() {
	Node* temp = this -> head;
	
	while (temp != nullptr) {
		cout << temp -> getData() << " ";
		temp = temp -> getNext();
	}	
	
	putchar('\n');
}

template<class ElemType>
int LinkedList<ElemType>::getLength() {
	return this -> length;	
}

template<class ElemType>
void LinkedList<ElemType>::clear() {
	Node* temp = this -> head;
	Node* storge = temp;
	
	while (temp != nullptr) {
		temp = temp -> getNext();
		delete storge;
		storge = temp;
	}	
	
	delete storge;
	this -> head = this -> tail = nullptr;
	this -> length = 0;
}

template<class ElemType>
bool LinkedList<ElemType>::deleteElementByParaPosition(int paraPosition) {
	if (paraPosition > this -> getLength()) {
		return 0;
	}
	
	if (paraPosition == 1) {
		return popHead();
	}
	
	int recordIndex = 1;
	Node* temp = this -> head;
	
	while (recordIndex < paraPosition - 1) {
		temp = temp -> getNext();	
		recordIndex++;
	}
	
	Node* recorder = temp -> getNext();
	temp -> setNext(recorder -> getNext());
	delete recorder;
	return 1;
}

template<class ElemType>
bool LinkedList<ElemType>::insertElement(int paraPosition, ElemType elem) {
	if (paraPosition > this -> getLength() + 1) {
		return 0;	
	}
	
	if (paraPosition == 1) {
		return this -> pushHead(elem);
	}
	
	Node* temp = this -> head;
	int recordIndex = 1;
	
	while (recordIndex < paraPosition - 1) {
		temp = temp -> getNext();
		recordIndex++;	
	}
	
	Node* newNode = new Node(elem, temp -> getNext());
	temp -> setNext(newNode);
	this -> length++;
	return 1;
}

template<class ElemType>
ElemType LinkedList<ElemType>::getElement(int paraPosition) {
	if (paraPosition > this -> length) {
		throw "out of range...";
	}
	
	int recordIndex = 1;
	Node* temp = this -> head;
	
	while (recordIndex < paraPosition) {
		temp = temp -> getNext();
		recordIndex++;
	}
	
	return temp -> getData();
}
	
remilia isMyWife() {
	 
	
	return 0;
}

重载pair的输出运算符

// 重载pair的输出运算符 
template<class T, class U>
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& p) {
  os << p.first << "x^" << p.second << " ";
  return os;
}

求和函数

// 参数使用pair 
// pair<系数, 指数>
LinkedList<pair<int, int>> add(LinkedList<pair<int, int>>& a, LinkedList<pair<int, int>>& b) {
	// Node是内部私有类, 因此这里使用自动类型进行推断 
	LinkedList<pair<int, int>> ans;
	
	auto iteratorA = a.initIterator();
	auto iteratorB = b.initIterator();
		
	while (iteratorA && iteratorB) {
		if (iteratorA -> getData().second < iteratorB -> getData().second) {
			ans.pushBack({iteratorA -> getData().first, iteratorA -> getData().second});
			iteratorA = iteratorA -> getNext();
		} else if (iteratorA -> getData().second > iteratorB -> getData().second) {
			ans.pushBack({iteratorB -> getData().first, iteratorB -> getData().second});
			iteratorB = iteratorB -> getNext();
		} else {
			int sum = iteratorA -> getData().second + iteratorB -> getData().second;
			
			if (sum) {
				ans.pushBack({sum, iteratorA -> getData().second});
			}
			
			iteratorA = iteratorA -> getNext();
			iteratorB = iteratorB -> getNext();
		}
	}
	
	while (iteratorA) {
		ans.pushBack({iteratorA -> getData().first, iteratorA -> getData().second});
		iteratorA = iteratorA -> getNext();
	}
	
	while (iteratorB) {
		ans.pushBack({iteratorB -> getData().first, iteratorB -> getData().second});
		iteratorB = iteratorB -> getNext();
	}
	
	a.clear();
	b.clear();
	return ans;
}

总体代码

#include <bits/stdc++.h>
#define remilia int
#define isMyWife main

using namespace std;

// 重载pair的输出运算符 
template<class T, class U>
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& p) {
  os << p.first << "x^" << p.second << " ";
  return os;
}

template<class ElemType>
class LinkedList {
	private:
		class Node {
				private:
					ElemType data;
					Node* next;
					
				public:
					virtual ~Node() {
							
					}
					
					Node();
					
					Node(ElemType data, Node* next) {
						this -> data = data;
						this -> next = next;	
					}
					
					ElemType getData() {
						return this -> data;
					}
					
					void setData(ElemType elem) {
						this -> data = elem;
					}
					
					Node* getNext() {
						return this -> next;
					}
					
					void setNext(Node* node) {
						this -> next = node;
					}
			};	
		
		int length;
		Node* head;
		Node* tail;
		
	public:
		
		virtual ~LinkedList();
		LinkedList();
		LinkedList(vector<ElemType> v);
		
		// 引入迭代器 
		Node* iterator;
				
		Node* initIterator() {
			return (this -> iterator = this -> head);
		}
		
		// get the length of linkedlist
		int getLength();
		
		// print all of the linkedlist
		void outputList();
		
		/**
		 * @brief  append a node to the tail
		 * @return the result of appending  1 -> success
		 * @param elem 
		 * the appending is always successful
		 **/
		bool pushBack(ElemType elem);
		
		/**
		 * @brief append a node to the head
		 * @param elem 
		 * @return the result of appending  1 -> success
		 * the appending is always successful
		 **/
		bool pushHead(ElemType elem);
		
		/**
		 * @brief delete a node from head
		 * @return the result of deleting 1 -> success, 0 -> failute
		 * the reason of failure is that the head node isn't existed
		 **/
		bool popHead();
		
		/**
		 * @brief delete a node from tail
		 * @return the result of deleting 1 -> success, 0 -> failute
		 * the reason of failure is that the tail node isn't existed
		 * @return 
		 **/
		bool popBack();
		
		
		// insert an element to the given position
		bool insertElement(int paraPosition, ElemType elem);
		
		/**
		 * @brief delete a node by the paraPosition
		 * @param the position of the node needed deleted
		 * @return 1 -> success, 0 -> fail
		 * the reason of failure is the position out of range
		 **/
		bool deleteElementByParaPosition(int paraPosition); 
		
		/**
		 * @brief clear the list
		 * 
		 **/
		void clear();
		
		/**
		 * @brief get a element by paraPosition
		 * 
		 * 
		 * @return the element
		 **/
		ElemType getElement(int paraPosition);
}; 


template<class ElemType>
LinkedList<ElemType>::~LinkedList() {
	
}

template<class ElemType>
LinkedList<ElemType>::LinkedList() {
	this -> length = 0;
	this -> head = this -> tail = nullptr;
}

template<class ElemType>
LinkedList<ElemType>::LinkedList(vector<ElemType> v) {
	for (auto e : v) {
		this -> pushBack(e);
	}
}

template<class ElemType>
bool LinkedList<ElemType>::pushBack(ElemType elem) {
	// if the tail equals null, the head equals null too
	if (this -> tail == nullptr) {
		this -> head = this -> tail = new Node(elem, nullptr);
	} else {
		Node* newTail = new Node(elem, nullptr);
		
		this -> tail -> setNext(newTail);
		this -> tail = newTail; 
	}
	
	this -> length++;
	return 1;
}

template<class ElemType>
bool LinkedList<ElemType>::pushHead(ElemType elem) {
	if (this -> head == nullptr) {
		this -> head = this -> tail = new Node(elem, nullptr);
	} else {
		Node* newTail = new Node(elem, head);
		
		this -> head = newTail;
	}
	
	this -> length++;
	return 1;
}

template<class ElemType>
bool LinkedList<ElemType>::popHead() {
	if (this -> length == 1) {
		this -> head = this -> tail = nullptr;
	}
	
	if (this -> head == nullptr) {
		return 0;
	} else {
		Node* temp = this -> head;
		this -> head = this -> head -> getNext();
		delete temp;
		return 1;
	}
}

template<class ElemType>
bool LinkedList<ElemType>::popBack() {
	if (this -> length == 1) {
		this -> head = this -> tail = nullptr;
	}
	
	if (this -> tail == nullptr) {
		return 0;
	} else {
		Node* temp = this -> head;
		
		while (temp -> getNext() != this -> tail) {
			temp = temp -> getNext();
		}
		
		delete temp -> getNext();
		
		this -> tail = temp;
		return 1;
	}
}

template<class ElemType>
void LinkedList<ElemType>::outputList() {
	Node* temp = this -> head;
	
	while (temp != nullptr) {
		cout << temp -> getData() << " ";
		temp = temp -> getNext();
	}	
	
	putchar('\n');
}

template<class ElemType>
int LinkedList<ElemType>::getLength() {
	return this -> length;	
}

template<class ElemType>
void LinkedList<ElemType>::clear() {
	Node* temp = this -> head;
	Node* storge = temp;
	
	while (temp != nullptr) {
		temp = temp -> getNext();
		delete storge;
		storge = temp;
	}	
	
	delete storge;
	this -> head = this -> tail = nullptr;
	this -> length = 0;
}

template<class ElemType>
bool LinkedList<ElemType>::deleteElementByParaPosition(int paraPosition) {
	if (paraPosition > this -> getLength()) {
		return 0;
	}
	
	if (paraPosition == 1) {
		return popHead();
	}
	
	int recordIndex = 1;
	Node* temp = this -> head;
	
	while (recordIndex < paraPosition - 1) {
		temp = temp -> getNext();	
		recordIndex++;
	}
	
	Node* recorder = temp -> getNext();
	temp -> setNext(recorder -> getNext());
	delete recorder;
	return 1;
}

template<class ElemType>
bool LinkedList<ElemType>::insertElement(int paraPosition, ElemType elem) {
	if (paraPosition > this -> getLength() + 1) {
		return 0;	
	}
	
	if (paraPosition == 1) {
		return this -> pushHead(elem);
	}
	
	Node* temp = this -> head;
	int recordIndex = 1;
	
	while (recordIndex < paraPosition - 1) {
		temp = temp -> getNext();
		recordIndex++;	
	}
	
	Node* newNode = new Node(elem, temp -> getNext());
	temp -> setNext(newNode);
	this -> length++;
	return 1;
}

template<class ElemType>
ElemType LinkedList<ElemType>::getElement(int paraPosition) {
	if (paraPosition > this -> length) {
		throw "out of range...";
	}
	
	int recordIndex = 1;
	Node* temp = this -> head;
	
	while (recordIndex < paraPosition) {
		temp = temp -> getNext();
		recordIndex++;
	}
	
	return temp -> getData();
}
	
// 参数使用pair 
// pair<系数, 指数>
LinkedList<pair<int, int>> add(LinkedList<pair<int, int>>& a, LinkedList<pair<int, int>>& b) {
	// Node是内部私有类, 因此这里使用自动类型进行推断 
	LinkedList<pair<int, int>> ans;
	
	auto iteratorA = a.initIterator();
	auto iteratorB = b.initIterator();
		
	while (iteratorA && iteratorB) {
		if (iteratorA -> getData().second < iteratorB -> getData().second) {
			ans.pushBack({iteratorA -> getData().first, iteratorA -> getData().second});
			iteratorA = iteratorA -> getNext();
		} else if (iteratorA -> getData().second > iteratorB -> getData().second) {
			ans.pushBack({iteratorB -> getData().first, iteratorB -> getData().second});
			iteratorB = iteratorB -> getNext();
		} else {
			int sum = iteratorA -> getData().second + iteratorB -> getData().second;
			
			if (sum) {
				ans.pushBack({sum, iteratorA -> getData().second});
			}
			
			iteratorA = iteratorA -> getNext();
			iteratorB = iteratorB -> getNext();
		}
	}
	
	while (iteratorA) {
		ans.pushBack({iteratorA -> getData().first, iteratorA -> getData().second});
		iteratorA = iteratorA -> getNext();
	}
	
	while (iteratorB) {
		ans.pushBack({iteratorB -> getData().first, iteratorB -> getData().second});
		iteratorB = iteratorB -> getNext();
	}
	
	a.clear();
	b.clear();
	return ans;
}

remilia isMyWife() {
	srand(time(NULL));
	LinkedList<pair<int, int>> a, b, c;
	
	for (int i = 1; i <= 10; i++) {
			a.pushBack({i, i});
		}
		
		for (int j = 10; j <= 20; j++) {
			b.pushBack({j, j});
		}
			
	c = add(a, b);
	c.outputList();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值