您的位置:首页 > 理论基础 > 数据结构算法

算法:一元多项式的表示及相加(链表实现)-数据结构(4)

2017-05-16 23:12 941 查看

一、算法问题描述

为了计算多个一元多项式相加,参照书上P40的式子相加,需要建立在有序链表的基础上,跟merge的算法类似。链表的基本操作就不表述了。书P39-P43

二、需要用到的数据结构

1、单链表

//=============单链表=====================
//int length_L = 0;//记录链表的长度 不包括头结点
typedef struct LNode{//结点类型
ElemType data;
struct LNode *next;//指向下一个节点的地址
}LNode, *LinkList;

typedef struct//链表类型
{
LinkList head;//结点的头
int len;
}Link;

Status InItList_L(Link &L){
//初始化线性链表 其中头结点为空
L.head = (LinkList)malloc(sizeof(LNode));
//L->data = -1;//设置头结点为空
L.head->next = NULL;
L.len = 0;
return OK;
}

Status GetElem_L(Link L, int i, ElemType &e){
//L是带头节点的单链表的头指针
//获取链表的第i个元素 返回值赋值到e元素 i[0.....n]
LinkList p = L.head->next;//这个是第一个节点
int j = 1;//当前指向的第几个结点 j[0....n] 由于头结点占用一个结点所以 元素的位置应该是从j-1开始

while (p)
{
if ((j - 1) == i)
{
//找到索引的位置了
e = p->data;
return OK;
}
p = p->next;//进去下个结点
j++;
}
//找不到的情况返回错误
return ERROR;
}

Status ListInsert_L(Link &L, int i, ElemType e){
//在带头结点的单链线性表L中的第i个位置插入元素e
LinkList p = L.head;
int j = 0;//当前指向的第几个结点
if (i == L.len)
{
//这个时候i的位置是链表的末尾 所以去到第i-1个位置上去
//当i的位置存在时候才能去到
while (p&& j - 1<i - 1)
{
//去到结点的第i-1个位置上
p = p->next;
j++;
}
//插入的位置是null的 但是在链表的头尾处是可以插入的 所以这里是新建一个结点
LNode *s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = NULL;

p->next = s;
L.len++;
return OK;
}
//当i的位置存在时候才能去到
while (p&& j - 1<i - 1)
{
//p去到结点的第i-1个位置上
p = p->next;
j++;
}
if (p == NULL || j - 1 != i - 1)
{
printf("ERROR j:%d\n", j);
//指针为空 或者结点没到i的位置的情况
return ERROR;
}
//生成s结点
LNode *s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = NULL;

s->next = p->next;
p->next = s;
L.len++;
return OK;

}

Status ListDelete_L(Link
4000
&L, int i, ElemType &e){
//在带头结点的单链表L中,删除第i个元素,并由e返回其值
if (!(i >= 0 && i <= L.len))
{
printf("i值位置非法");
return ERROR;
}
LinkList p = L.head;
int j = 0;//当前指向的第几个结点
while (p&& j - 1<i - 1)
{
//p去到结点的第i-1个位置上
p = p->next;
j++;
}
//删除操作
e = p->next->data;
p->next = p->next->next;
L.len--;
return OK;

}
void PrintfList_L(Link &L){
//打印链表的元素
LinkList p = L.head->next;
printf("长度:%d \n", L.len);
printf("打印链表 ");
while (p)
{
printf("%.0lf:%d || ", p->data.coef,p->data.expn);
p = p->next;
}
printf("\n");
}

2、系数和指数结构

typedef struct{//项的表示,多项式的项作为LinkList的数据元素
float coef;//系数
int expn;//指数
}term, ElemType;

三、算法实现

//===============2.4算法 一元多项式的表示和相加=========================
//创建Link多项式
void CreatePolyn(Link &L,ElemType *elem,int m){
InItList_L(L);
for (int i = 0; i < m; i++)
{
ListInsert_L(L, i, elem[i]);
}
}

void AddPolyn(Link &Pa,Link &Pb){
//多项式加法:Pa = Pa +Pb 两个多项式相加
LinkList pa = Pa.head->next;//指向第0个元素
LinkList pb = Pb.head->next;//指向第0个元素
int indexPa = 0;//当前pa指向的位置索引
while (pa && pb)
{
//指向的结点都不为空的情况下
int expnA = pa->data.expn;
int expnB = pb->data.expn;
if (expnA < expnB){
indexPa++;
pa = pa->next;
}
else if (expnA > expnB)
{
ListInsert_L(Pa, indexPa + 1, pb->data);
pb = pb->next;
}
else
{
//相等的情况下
pa->data.coef += pb->data.coef;
pa = pa->next;
indexPa++;
pb = pb->next;
}
}
//插入剩余段
while (pb)
{
//如果pb还没完的时候
ListInsert_L(Pa, indexPa,pb ->data);
pb = pb->next;
indexPa++;
}
}

四、执行

//一元多项式的链表
//创建多项式A
ElemType elemA[4] = { { 1, 1 }, { 2, 2 }, { 3, 3 }, { 4, 4 } };
Link listA;
CreatePolyn(listA, elemA, 4);
PrintfList_L(listA);
//创建多项式B
ElemType elemB[5] = { { 1, 1 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 9, 9 } };
Link listB;
CreatePolyn(listB, elemB, 5);
PrintfList_L(listB);

AddPolyn(listA, listB);
PrintfList_L(listA);


输出:
长度:4
打印链表 1:1 || 2:2 || 3:3 || 4:4 ||
长度:5
打印链表 1:1 || 3:3 || 4:4 || 5:5 || 9:9 ||
长度:6
打印链表 2:1 || 2:2 || 6:3 || 8:4 || 5:5 || 9:9 ||
请按任意键继续. . .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: