一.简述

  利用链表表示稀疏多项式,并基于之前的一些操作(编程实现上还是有所不同的)组合新的操作实现一元多项式的表示及相加。

  二.ADT

 抽象数据类型一元多项式的定义
ADT Polyomail{
数据对象:D = {a[i]|a[i]属于TermSet, i = ,,...,m,m>=
TermSet中每个元素包含一个表示系数的实数和表示指数的整数}
数据关系
基本操作:
CreatPolyn(&P, m)
操作结果:输入 m 项的系数和指数,建立一元多项式 P
DestroyPolyn(&P)
初始条件:一元多项式 P 已存在
操作结果:销毁一元多项式P
PrintPolyn(P)
初始条件:一元多项式 P 已存在
操作结果:打印输出一元多项式 P
PolynLength(P)
初始条件:一元多项式 P 已存在
操作结果:返回一元多项式中 P 的项数
AddPolyn(&Pa, &Pb)
初始条件:一元多项式 Pa 和 Pb 已存在
操作结果:完成多项式相加运算,即:Pa = Pa + Pb,并销毁一元多项式 Pb
SubtractPolyn(&Pa, &Pb)
初始条件:一元多项式 Pa 和 Pb 已存在
操作结果:完成多项式相减运算,即 Pa = Pa - Pb,并销毁一元多项式 Pb
MultiplyPolyn(&Pa, &Pb)
初始条件:一元多项式 Pa 和 Pb 已存在
操作结果:完成多项式相乘运算,即 Pa = Pa x Pb,并销毁一元多项式 Pb
}ADT Polynomial
*/

  三.头文件

 //2_4.h
/**
《数据结构(C语言版)》 Page 37
....为此,从实际应用角度出发重新定义线性链表及其基本操作....
*/
/**
author:zhaoyu
email:zhaoyu1995.com@gmail.com
date:2016-6-6
note:realize my textbook <<数据结构(C语言版)>>
*/
#ifndef _2_4_H_
#define _2_4_H_
#include "head.h"
typedef struct{//项的表示,多项式的项作为LinkList的数据元素
float coef;//系数
int expn;//指数
}term, ElemType;//两个类型名:term用于本ADT,ElemType为LinkList的数据对象名
typedef struct LNode{
ElemType data;
struct LNode *next;
}*Link, *Position;
typedef struct{//链表类型
Link head, tail;//分别指向线性链表中的头结点和最后一个结点
int len;//指示线性链表中数据元素的个数
}LinkList;
typedef LinkList polynomial;//用带表头结点的有序链表表示多项式 int cmp(term a, term b)
{
//依据 a 的指数值 <(或=)(或>) b 的指数值 ,返回 -1 ,0, +1
if(a.expn < b.expn)
{
return -;
}
else if (a.expn == b.expn)
{
return ;
}
else
{
return ;
}
}
Status InitList(LinkList &L)
{
//构造一个空的线性表L
L.head = (Link)malloc(sizeof(struct LNode));
L.head->data.coef = 0.0;
L.head->data.expn = -;
L.head->next = NULL;
L.tail = L.head->next;
L.len = ;
}
Position GetHead(LinkList L)
{
//返回线性链表 L 中头结点的位置
return L.head;
}
Status SetCurElem(Link &p, ElemType e)
{
//已知 p 指向线性链表中的一个结点,用 e 更新 p 所指结点中数据元素的值
p->data.coef = e.coef;
p->data.expn = e.expn;
return OK;
}
Status LocateElem(LinkList L, ElemType e, Position &q, Status (* compare)(ElemType, ElemType))
{
//若有序链表 L 中存在与 e 满足判定函数 compare() 取值为 0 的函数
//则 q 指示 L 中第一个值为 e 的结点的位置,并返回 TRUE;否则 q 指示
//第一个与 e 满足compare() 取值>0的元素的前驱的位置,并返回FLASE
Link temp = L.head->next;
while (temp != NULL)
{
if ( == (* compare)(temp->data, e))
{
q = temp;
return TRUE;
}
temp = temp->next;
}
temp = L.head;
while (temp->next != NULL)
{
if ((* compare)(temp->next->data, e) > )
{
q = temp;
return FALSE;
}
temp = temp->next;
}
q = temp;
return FALSE;
}
Status MakeNode(Link &p, ElemType e)
{
//分配由 p 指向的值为 e 的结点,并返回 OK;若分配失败,则返回 ERROR
p = (Link)malloc(sizeof(struct LNode));
if (!p)
{
return ERROR;
}
p->data.coef = e.coef;
p->data.expn = e.expn;
p->next = NULL;
return OK;
}
Status InsFirst(Link &h, Link &s)
{
//已知 h 指向线性链表的头结点,将 s 所指节点插入在第一个结点之前
if (NULL == h)
{
return ERROR;
}
else
{
s->next = h->next;
h->next = s;
}
return OK;
}
ElemType GetCurElem(Link p)
{
//已知 p 指向线性链表中的一个节点,返回 p 所指结点中数据元素的值
if (p != NULL)
{
return p->data;
}
else
{
exit(ERROR);
}
}
/**
My Code
*/
Position NextPos(LinkList L, Link p)
{
//已知 p 指向线性链表 L 中的一个节点,返回 p 所指结点
//的直接后继的位置,若无后继,返回 NULL
Link q = L.head;
while (q->next != NULL)
{
if(q == p)
{
return p->next;
}
q = q->next;
}
return NULL;
}
Status DelFirst(Link &h, Link &q)
{
//已知 h 指向线性链表的头结点,删除链表中的第一个节点并以 q 返回
if (h == NULL)
{
return ERROR;
}
q = h->next;
h->next = q->next;
q->next = NULL;
return OK;
}
Status FreeNode(Link &p)
{
//释放 p 所指节点
p = NULL;//便于回收???释放后再次使用
free(p);
}
Status ListEmpty(LinkList L)
{
//若线性链表 L 为空,则返回 TRUE,否则返回 FALSE
if (L.head->next == NULL)
{
return TRUE;
}
else
{
return FALSE;
}
}
Status Append(LinkList &L, Link &s)
{
//将指针 s 所指(彼此以指针相链)的一串结点
//链接在线性链表 L 最后一个结点
Link q = L.head;
while (q->next != NULL)
{
q = q->next;
}
q->next = s;
int cnt = ;
Link temp = s;
while (temp != NULL)
{
cnt++;
if (NULL == temp->next)
{
L.tail = temp;//注意更新尾指针
}
temp = temp->next;//注意这一句要放在最后,否则可能访问非法内存
} L.len += cnt;
//注意要根据这一串结点长度增加链表长度
return OK;
}
void PrintPolyn(polynomial P)
{
Link temp = P.head->next;
while (temp != NULL)
{
printf("%.1f\t", temp->data.coef);
temp = temp->next;
}
printf("\n");
temp = P.head->next;
while (temp != NULL)
{
printf("%d\t", temp->data.expn);
temp = temp->next;
}
printf("\n");
}
/**
algorithm 2.22
*/
void CreatPolyn(polynomial &P, int m)
{
//输入 m 项的系数和指数,建立表示一元多项式的有序链表 P
InitList(P);
Link h = GetHead(P), s, q;
ElemType e;
e.coef = 0.0;
e.expn = -;
SetCurElem(h, e);//设置头结点中的数据元素
for (int i = ; i <= m; i++)
{//依次输入 m 个非零项
scanf("%f%d", &e.coef, &e.expn);
if (!LocateElem(P, e, q, (* cmp)))
{//当前链表中不存在该指数项
if (MakeNode(s, e))
{
InsFirst(q, s);
}
}
}
}//CreatePolyn
/**
algorithm 2.23
*/
void AddPolyn(polynomial &Pa, polynomial &Pb)
{
//多项式加法:Pa = Pa + Pb,利用两个多项式构成和多项式
Link ha = GetHead(Pa);
Link hb = GetHead(Pb);//pa 和 pb 分别指向 Pa 和 Pb 的头结点
Link qa = NextPos(Pa, ha);
Link qb = NextPos(Pb, hb);//qa 和 qb 分别指向 Pa 和 Pb 中当前节点
while (qa && qb)//qa 和 qb均非空
{
ElemType a = GetCurElem(qa);
ElemType b = GetCurElem(qb);//a、b为两表中当前比较元素
switch ((* cmp)(a, b))
{
case -://多项式 Pa 中当前节点的指数值小
{
ha = qa;
qa = NextPos(Pa, qa);//printf("%d\n", qa->data.expn);
break;
}
case ://两者的指数值相等
{
ElemType S = {a.coef + b.coef, a.expn};
if( != S.coef)
{//修改多项式 Pa 中当前节点
SetCurElem(qa, S);
ha = qa;
}
else
{//删除多项式中 Pa 当前节点
DelFirst(ha, qa);
FreeNode(qa);
}
DelFirst(hb, qb);
FreeNode(qb);
qa = NextPos(Pa, ha);
qb = NextPos(Pb, hb);
break;
}
case ://多项式 Pb 当前结点指数值小
{
DelFirst(hb, qb);
InsFirst(ha, qb);
qb = NextPos(Pb, hb);
ha = NextPos(Pa, ha);
break;
}
}//switch
}//while
if (!ListEmpty(Pb))
{
Append(Pa, qb);//链接 Pb 中剩余结点
}
FreeNode(hb);//释放 Pb 的头结点
}//AddPolyn
#endif

  四.CPP文件

 #include "2_4.h"

 int main(int argc, char const *argv[])
{
polynomial Pa, Pb, Pc;
int n;
printf("Input n\t");
scanf("%d", &n);
CreatPolyn(Pa, n);
printf("Pa\n");
PrintPolyn(Pa);
printf("Input n\t");
scanf("%d", &n);
CreatPolyn(Pb, n);
printf("Lb\n");
PrintPolyn(Pb);
AddPolyn(Pa, Pb);
printf("La + Lb\n");
PrintPolyn(Pa);
return ;
}

  五.测试

  六.小结

  不要对着伪代码一行行敲代码,一定要在理解的基础上实现算法,否则敲错一个变量导致奇怪的错误也要大费周折才能找到。

数据结构算法C语言实现(六)---2.4一元多项式的表示及相加的更多相关文章

  1. 数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

    一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚, ...

  2. 数据结构算法C语言实现(五)---2.3重新定义线性链表及其基本操作

    一.简述 ...由于链表在空间的合理利用上和插入.删除时不需要移动等的优点,因此在很多场合下,它是线性表的首选存储结构.然而,它也存在着实现某些基本操作,如求线性表的长度时不如顺序存储结构的缺点:另一 ...

  3. 数据结构算法C语言实现(二)---2.3线性表的链式表示和实现之单链表

    一.简述 [暂无] 二.头文件 #ifndef _2_3_part1_H_ #define _2_3_part1_H_ //2_3_part1.h /** author:zhaoyu email:zh ...

  4. 数据结构算法C语言实现(二十七)--- 7.2图的遍历

    一.简述 栈与队列,DFS与BFS.仅以连接表为例实现. 二.头文件 BFS要用到的头文件 //3_4_part1.h /** author:zhaoyu email:zhaoyu1995.com@g ...

  5. 数据结构算法C语言实现(二十)--- 6.3.1遍历二叉树

    一.简述 二叉树的遍历主要是先序.中序.后序及对应的递归和非递归算法,共3x2=6种,其中后序非递归在实现上稍复杂一些.二叉树的遍历是理解和学习递归及体会栈的工作原理的绝佳工具! 此外,非递归所用的栈 ...

  6. 数据结构算法C语言实现(十二)--- 3.4循环队列&队列的顺序表示和实现

    一.简述 空队列的处理方法:1.另设一个标志位以区别队列是空还是满:2.少用一个元素空间,约定以队列头指针在队尾指针下一位置上作为队列呈满的状态的标志. 二.头文件 //3_4_part1.h /** ...

  7. 数据结构算法C语言实现(十一)--- 3.4队列的链式表示和实现

    一.简介 FIFO. 二.头文件 //3_4_part1.h /** author:zhaoyu email:zhaoyu1995.com@gmail.com date:2016-6-9 note:r ...

  8. 数据结构算法C语言实现(十)--- 3.3栈与递归的实现

    一.简介 汉诺塔问题是递归的一个典型例子,而且书上的讲解很详细,对理解C语言函数及函数传参的工作机制很有帮助,值得一看.而且,递归在我看来和分治.DP.贪心等一样是十分优美的思想,值得学习!!! 二. ...

  9. 数据结构算法C语言实现(七)--- 3.1栈的线性实现及应用举例

    一.简述 栈,LIFO.是操作受限的线性表,和线性表一样有两种存储表示方法.下面以顺序存储为例,实现. 二.ADT 暂无. 三.头文件 //3_1.h /** author:zhaoyu email: ...

随机推荐

  1. 洛谷 1016 / codevs 1046 旅行家的预算

    https://www.luogu.org/problem/show?pid=1016 http://codevs.cn/problem/1046/ 题目描述 Description 一个旅行家想驾驶 ...

  2. YII框架概念与安装

    Yii概念: YII安装:      下载最版本http://www.framework.com      解压至访问目录下 直接打开advanced/init.bat文件输入0之后输入yes 打不开 ...

  3. MFC添加背景图片

    1.在资源里导入一个bmp图片假设名称为IDB_BITMAP1 实现OnPaint方法 CPaintDC dc(this); CRect rect; GetClientRect(&rect); ...

  4. 纯C#实现Hook功能

    发布一个自己写的用于Hook .Net方法的类库,代码量不大,完全的C#代码实现,是一个比较有趣的功能,分享出来希望能和大家共同探讨 安装:Install-Package DotNetDetour源码 ...

  5. [转]Linux系统中‘dmesg’命令处理故障和收集系统信息的7种用法

    'dmesg'命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构.cpu.挂载的硬件,RAM等多个运行级别的大量的系统信息.当计算机启动时,系统内核(操作系统的核心部分)将会被加载到 ...

  6. WordPress使用固定链接

    WordPress安装后我们会发现,文章默认的url是很丑的,http://example.com/?p=N,其中N是文章ID,一串数字.默认链接在所有的环境下都运转良好,但和其他的类型比起来却没那么 ...

  7. SQLite常用点滴总结(转)

    expressionexpr ::=     expr binary-op expr |expr [NOT] like-op expr [ESCAPE expr] |unary-op expr |( ...

  8. Spring + Spring MVC+Hibernate框架整合详细配置

    来源于:http://www.jianshu.com/p/8e2f92d0838c 具体配置参数: Spring: spring-framework-4.2.2Hibernate: hibernate ...

  9. 安卓activity生命周期

    相信不少朋友也已经看过这个流程图了,也基本了解了Activity生命周期的几个过程,我们就来说一说这几个过程. 1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法, ...

  10. SVM与LR的区别以及SVM的优缺点

    对于异常数据,SVM比LR更好 SVM的优缺点: 优点:1.提供非常精确的分类器 2.更少的过拟合(因为有L2正则化项0.5||w||2),对噪声数据更加鲁棒(因为损失函数的原因) 缺点:1.SVM是 ...