线性表之一元多项式求和

    在数学上,一个一元多项式可以按照升幂表示为:A(x)=a0+a1x+a2x^2+a3x^3+...+anx^n,它由n+1个系数唯一确定。因此可以用一个线性表(a0,a1,a2...an)来表示,每一项的指数i隐含在系数ai的序号。

    若有A(x)=a0+a1x+a2x^2+a3x^3+...+anx^n 和 B(x)=b0+b1x+b2x^2+b3x^3+...+bmx^m,一元多项式求和就是合并同类项的过程。

    在实际应用中,多项式的指数可能很高并且变化会很大,在表示多项式的线性表中就会存在很多零元素。一个较好的方法就是只存储非零项,但是需要在存储非零系数的同时存储相应的指数。这样一个一元多项式的每一个非零项可以由其系数和指数唯一确定。

    采用顺序表实现两个一元多项式相加的性能不好,采用单链表存储,每一个非零项对应一个结点,且单链表应该递增有序排列。

    结点的实现:

struct Elem{
	int cef;		//系数
	int exp;		//指数
};

struct Node{
	Elem e;
	Node *next;
};


     设两个工作指针p和q分别指向两个单链表A和B的开始结点。

     算法实现:

     1.工作指针pre,p,qre,q初始化

     2.while(p存在且q存在)执行下列三种情形之一:

        2.1如果p->exp小于q->exp,则指针p后移

        2.2如果p->exp大于q->exp,则

             2.2.1将结点q插入到结点p之前

             2.2.2将指针q指向原指结点的下一个结点

        2.3如果p->exp等于q->exp,则

             2.3.1p->coef=p->coef+q->coef

             2.3.2如果p->coef==0,则执行下列操作,否则指针p后移

                     2.3.2.1删除结点p

                     2.3.2.2使得指针p指向它原指结点的下一个结点

            2.3.3删除结点q

            2.3.4使得指针q指向它原指结点的下一个结点

      3.如果q不为空,将结点q链接在第一个单链表后面


linklist.h

class LinkList{
	friend void Add(LinkList &A, LinkList &B);
private:
	Node *first;
public:
	LinkList();
	LinkList(int a[][MaxSize],int n);
	~LinkList();
	int Length();
	Elem Get(int i);
	int Locate(Elem e);
	void Insert(int i,Elem em);
	Elem Delete(int i);
	void PrintList();
	void setHead(Node *p);
};

linklist.cpp

void Add(LinkList &A, LinkList &B){
	Node *pre = A.first, *p = pre->next;
	Node *qre = B.first, *q = qre->next;
	while (p != NULL&&q != NULL){
		if (p->e.exp > q->e.exp){
			Node *v = q->next;
			pre->next = q;
			q->next = p;
			q = v;
		}
		else if (p->e.exp < q->e.exp){
			pre = p;
			p = pre->next;
		}
		else{
			p->e.cef += q->e.cef;
			if (p->e.cef == 0){
				pre->next = p->next;
				delete p;
				p = pre->next;
			}
			else{
				pre = p;
				p = pre->next;
			}
			qre->next = q->next;
			delete q;
			q = qre->next;
		}
	}
	if (q != NULL)pre->next = q;
	//B.setHead(NULL);
	delete B.first;
	B.first = NULL;
}

LinkList::LinkList(){
	first = new Node;
	first->next = NULL;
}

LinkList::LinkList(int a[][MaxSize], int n){
	first = new Node;
	Node *r = first;
	for (int i = 0; i < n; i++){
		Node *s = new Node;
		s->e.cef = a[0][i];
		s->e.exp = a[1][i];
		r->next = s;
		r = s;
	}
	r->next = NULL;
}

LinkList::~LinkList(){
	while (first != NULL){
		Node *p = first;
		first = first->next;
		delete p;
	}
}

Elem LinkList::Get(int i){
	Node *p = first->next;
	int count = 1;
	while (p != NULL&&count < i){
		p = p->next;
		count++;
	}
	if (p == NULL)
		throw"wrong location!";
	else
		return p->e;
}

int LinkList::Length(){
	int length = 0;
	Node *p = first->next;
	while (p != NULL){
		p = p->next;
		length++;
	}
	return length;
}

int LinkList::Locate(Elem em){
	Node *p = first->next;
	int count = 1;
	while (p != NULL){
		if (p->e.cef == em.cef&&p->e.exp == em.exp){
			return count;
		}
		else{
			p = p->next;
			count++;
		}
	}
	return 0;
}

void LinkList::Insert(int i, Elem em){
	Node *p = first;
	int count = 1;
	while (p != NULL&&count < i){
		p = p->next;
		count++;
	}
	if (p == NULL)
		throw"wrong location!";
	else{
		Node *s = new Node;
		s->e = em;
		s->next = p->next;
		p->next = s;
	}
}

Elem LinkList::Delete(int i){
	Node *p = first;
	int count = 1;
	while (p != NULL&&count < i){
		p = p->next;
		count++;
	}
	if (p == NULL)
		throw"wrong location!";
	else{
		Node *q = p->next;
		Elem em = q->e;
		p->next = q->next;
		delete q;
		return em;
	}
}

void LinkList::PrintList(){
	Node *p = first->next;
	while (p != NULL){
		cout << p->e.cef << "\t" << p->e.exp << endl;
		p = p->next;
	}
	cout << endl;
}

void LinkList::setHead(Node *p){
	first = p;
}

main.cpp

int main(){
	int a[2][MaxSize] = {
		{1,3,-1,3},
		{2,3,4,5}
	};
	int b[2][MaxSize] = {
		{2,-3,2 }, 
		{1,3,4}
	};
	LinkList A(a, 4);
	LinkList B(b, 3);
	A.PrintList();
	B.PrintList();
	Add(A, B);
	A.PrintList();
}

测试结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值