您的位置:首页 > 其它

Polynomial 一元多项式的表示及相加 (线性链表实现 严蔚敏版)

2012-04-15 22:58 501 查看
1、贴代码:

#include <iostream>
#include <cstdio>
using namespace std;

struct Node {
double coef;
int expn;
Node *next;
};

void CreatPolynomial(Node *&head, int n)		//	生成带表头结点的单链表,除头结点外另生成n个结点
{
head = (Node *)malloc(sizeof(Node));
head->coef = 0;
head->expn = 0;
head->next = NULL;							//	初始化头结点
cout << "请输入各项系数及指数:" << endl;
Node *p = head;
for(int i = 0; i < n; i++) {
p->next = (Node *)malloc(sizeof(Node));	//	生成新结点,尾插入生成链表
p = p->next;
cin >> p->coef >> p->expn;
p->next = NULL;
}
}

void PrintPolynomial(Node *&head)
{
if(head->next == NULL)							//	结果是0时直接输出0
putchar('0');
else {
for(Node *p = head->next; p != NULL; p = p->next) {
if(p != head->next && p->coef >0)		//	当p非首项且指向的系数为正时才输出'+'
putchar('+');						//	之前只判定了p->coef >0

if(p->coef == 1) {						//	系数为1或-1时特殊处理
if(p->expn == 0)
putchar('1');					//	判断条件不能写在一起:
}										//	if(p->coef == 1 && p->expn == 0) putchar('1');
else if(p->coef == -1)
putchar('-');
else
cout << p->coef;

switch(p->expn) {						//  指数为0或1时特殊处理

case 0:
break;

case 1:
putchar('x');
break;

default:
p->expn < 0 ? printf("x^(%d)", p->expn) : printf("x^%d", p->expn);	//	指数小于0时打括号
break;
}
}
}
cout << endl;
}
//	上面的函数中若系数为int型,那么也可以改为switch结构,这是C语言的缺陷?

void Free(Node *&head)
{
Node *q = NULL;
for(Node *p = head; p != NULL; p = q) {
q = p->next;
free(p);
}
}

char cmp(int a, int b)
{
if(a > b)
return '>';
if(a < b)
return '<';
return '=';
}

void AddPolynomial(Node *&pA, Node *&pB)		//	传进两个链表的头指针
{
Node *ha = pA;
Node *hb = pB;
Node *qa = ha->next;						//	ha, hb分别跟在qa, qb的后一位置
Node *qb = hb->next;						//	qa, qb分别指向Pa, Pb中当前比较元素
while(qa && qb)
{
double sum = 0;
int a = qa->expn;
int b = qb->expn;
switch( cmp(a, b) ) {

case '<':
ha = qa;
qa = qa->next;						//	非ha = ha->next;
break;

case '=':
sum = qa->coef + qb->coef;
if(sum != 0.0) {
qa->coef = sum;
ha = qa;
}
else {
if(ha->next != qa)
cout << "Error: ha->next != qa" << endl;
ha->next = ha->next->next;		//  删除和为0的结点,ha不变,还在qa后一位置
free(qa);
}
if(hb->next != qb)
cout << "Error: hb->next != qb" << endl;
hb->next = hb->next->next;
free(qb);
qb = hb->next;
qa = ha->next;
break;

case '>':
hb->next = hb->next->next;			//	删除qb指向的结点
qb->next = ha->next;				//	将qb插入ha后qa前
ha->next = qb;

qb = hb->next;						//	not qb = ha->next
ha = ha->next;
break;

default:
cout << "Error!" << endl;
break;
}
}
if(qb)
ha->next = qb;
free(hb);
}

int main(void)
{
//	freopen("cin.txt", "r", stdin);
Node *A = NULL;
Node *B = NULL;
int lenA;
int lenB;
while(cout << "请输入A的项数:" << endl, cin >> lenA) {
CreatPolynomial(A, lenA);					//	生成A链表
cout << "请输入B的项数:" << endl;			//	生成B链表
cin >> lenB;
CreatPolynomial(B, lenB);

cout << " A = ";							//	输出A链表
PrintPolynomial(A);
cout << " B = ";							//	输出B链表
PrintPolynomial(B);

AddPolynomial(A, B);						//	A = A + B
cout << "A+B= ";
PrintPolynomial(A);							//	输出和
cout << endl;

Free(A);									//	务必释放结点
}
return 0;
}


2、运行:



附一些宝贵的测试数据:

5
-2 -1
-3 0
8 1
3 5
-2 7
5
4 -1
6 0
3 5
1 7
1 8

3
2 1
5 8
-3.1 11
3
7 0
-5 8
11 9

4
6 -3
-1 1
4.4 2
-1.2 9
3
6 -3
-4.4 2
-7.8 15

6
1 0
1 1
1 2
1 3
1 4
1 5
2
-1 3
-1 4

2
1 1
1 3
2
-1 1
-1 3

2
1 1
1 100
2
1 100
1 200

3
1 1
1 2
1 3
0

以上数据的运行结果:





3、想法:

1)那个函数完全对着书写的,不过之前吃了些苦头

。用带头结点的链表好啊!(针对本题,不然首项的那些特殊情况要烦死人。)

2)在输出上花了些工夫,不过还怕有些小错误,之前也想了很多情况,够复杂的了!

2012/5/1更新:

代码中“初始化”结构体可用memset
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: