目录
题目
将多项式Pa和Pb合并,并以Pa返回,同时删除Pb
代码
1.全部代码
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct
{//项的表示
float coef;//系数
int expn;//指数
}ElemType;//声明数据元素结构布局
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LNode, * Link, * Position;//声明结点结构布局
typedef struct
{
Link head, tail;
}LinkList;
typedef LinkList Polynomial;//将带头结点的链表定义为多项式
void SetCurElem(Link, ElemType);
Status MakeNode(Link*, ElemType);
Status InitPolyn(Polynomial*);
Status CreatePolyn(Polynomial*);
void PrintPolyn(Polynomial);
void AddPolyn(Polynomial*, Polynomial*);
int cmp(ElemType, ElemType);
Position GetHead(Polynomial);
Position GetLast(Polynomial);
Position NextPos(Link);
ElemType GetCurElem(Link);
void DelFirst(Link, Link*);
void InsFirst(Link, Link);
void Append(Polynomial*, Link);//tail指针改变了,希望得到这种改变
void FreeNode(Link);
int main()
{
Polynomial Pa, Pb;
CreatePolyn(&Pa);
CreatePolyn(&Pb);
printf("Output Pa:\n");
PrintPolyn(Pa);
printf("\nOutput Pb:\n");
PrintPolyn(Pb);
AddPolyn(&Pa, &Pb);
printf("\nResult Pa:\n");
PrintPolyn(Pa);
return 0;
}
//1.将p所指结点的数据元素设置为e
void SetCurElem(Link p, ElemType e)
{
p->data.coef = e.coef;
p->data.expn = e.expn;
}
//2.用指针p承接动态分匹配的结点的地址,并将数据元素设置为e
Status MakeNode(Link* pp, ElemType e)
{
*pp = (Link)malloc(sizeof(LNode));
if (!*pp)return ERROR;
SetCurElem(*pp, e);
(*pp)->next = NULL;
return OK;
}
//3.建立带头结点的链表(多项式)
Status InitPolyn(Polynomial* pP)
{
ElemType e = { 0.0,-1 };
MakeNode(&pP->head, e);
if (!pP->head)return ERROR;
pP->tail = pP->head;//tial是尾指针,初始化
return OK;
}
//4.建立完整的链表
Status CreatePolyn(Polynomial* pP)
{
InitPolyn(pP);
Link p;
ElemType e;
int i, n;
printf("enter the number of Polyn:\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("enter coef,expn:\n");
scanf("%f,%d", &e.coef, &e.expn);
MakeNode(&p, e);//建立新结点
if (!p)return ERROR;
pP->tail->next = p;
pP->tail = p;//更新尾指针
}
return OK;
}
//5.打印多项式
void PrintPolyn(Polynomial P)
{
Link p, h = GetHead(P);
p = NextPos(h);
int k = 0;//表示项的位置
ElemType e;
while (p)
{
e = GetCurElem(p);
printf("%dth %5.2fx[%d]\n", ++k, e.coef, e.expn);
p = NextPos(p);
}
printf("--------Print finished-------");
}
//6.多项式相加
void AddPolyn(Polynomial* pPa, Polynomial* pPb)
{
Link ha, hb, pa, pb, prev, q;//prev记录pa前一个结点的位置
ElemType a, b;
float sum = 0.0;
ha = GetHead(*pPa); hb = GetHead(*pPb);
pa = NextPos(ha); pb = NextPos(hb);
prev = ha;
while (pa && pb)
{
a = GetCurElem(pa); b = GetCurElem(pb);
switch (cmp(a, b))
{
case -1://a的指数小,不对多项式Pb操作
{
prev = pa; pa = NextPos(pa); break;
}
case 0:
{
sum = a.coef + b.coef;
if (sum)//系数非0,更改Pa的系数,对地址操作!
{
pa->data.coef=sum; prev = pa;//a.coef=sum错
}
else//系数为0,删除pa所指结点,同时更新pa(之后统一),prev
{
DelFirst(prev, &pa); FreeNode(pa);
if (pa == GetLast(*pPb))pPb->tail = prev;//注意尾指针所指结点可能被删除了
//及时更改尾指针
}
DelFirst(hb, &q);FreeNode(q);//删除Pb当前结点
pa = NextPos(prev); pb = NextPos(hb); break;
}
case 1://a的指数大,将多项式Pb当前结点插入Pa当前结点之前
{
DelFirst(hb, &q);
InsFirst(prev, q);
pb = NextPos(hb); pa = NextPos(pa);
}
}
}
if (pb)
{
Append(pPa, pb);//注意Append函数和InsFirst函数的区别
pPa->tail = pPb->tail;
}
FreeNode(hb);
}
//7.获得头指针
Position GetHead(Polynomial P)
{
return P.head;
}
//8.获得尾指针
Position GetLast(Polynomial P)
{
return P.tail;
}
//9.指针p后移一位
Position NextPos(Link p)
{
return p->next;
}
//10.获得当前数据元素
ElemType GetCurElem(Link p)
{
return p->data;
}
//11.比较指数大小
int cmp(ElemType a, ElemType b)
{
return(a.expn == b.expn ? 0 : (a.expn > b.expn ? 1 : -1));
}
//12.删除指针h所指结点的后一个结点
void DelFirst(Link h, Link* pq)
{
*pq = NextPos(h);
h->next = NextPos(*pq);
}
//13.指针s所指结点插入p所指结点后
void InsFirst(Link p, Link s)
{
s->next = NextPos(p);
p->next = s;
}
//14.将指针p所指结点(及之后的结点)链接在多项式后
void Append(Polynomial* pP, Link p)
{
pP->tail->next = p;
}
//15.释放指针p所指结点内存
void FreeNode(Link p)
{
free(p);
}
2.头文件和宏定义
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct
{//项的表示
float coef;//系数
int expn;//指数
}ElemType;//声明数据元素结构布局
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LNode, * Link, * Position;//声明结点结构布局
typedef struct
{
Link head, tail;
}LinkList;
typedef LinkList Polynomial;//将带头结点的链表定义为多项式
void SetCurElem(Link, ElemType);
Status MakeNode(Link*, ElemType);
Status InitPolyn(Polynomial*);
Status CreatePolyn(Polynomial*);
void PrintPolyn(Polynomial);
void AddPolyn(Polynomial*, Polynomial*);
int cmp(ElemType, ElemType);
Position GetHead(Polynomial);
Position GetLast(Polynomial);
Position NextPos(Link);
ElemType GetCurElem(Link);
void DelFirst(Link, Link*);
void InsFirst(Link, Link);
void Append(Polynomial*, Link);//tail指针改变了,希望得到这种改变
void FreeNode(Link);
3.主函数
int main()
{
Polynomial Pa, Pb;
CreatePolyn(&Pa);
CreatePolyn(&Pb);
printf("Output Pa:\n");
PrintPolyn(Pa);
printf("\nOutput Pb:\n");
PrintPolyn(Pb);
AddPolyn(&Pa, &Pb);
printf("\nResult Pa:\n");
PrintPolyn(Pa);
return 0;
}
4.核心函数
//多项式相加
void AddPolyn(Polynomial* pPa, Polynomial* pPb)
{
Link ha, hb, pa, pb, prev, q;//prev记录pa前一个结点的位置
ElemType a, b;
float sum = 0.0;
ha = GetHead(*pPa); hb = GetHead(*pPb);
pa = NextPos(ha); pb = NextPos(hb);
prev = ha;
while (pa && pb)
{
a = GetCurElem(pa); b = GetCurElem(pb);
switch (cmp(a, b))
{
case -1://a的指数小,不对多项式Pb操作
{
prev = pa; pa = NextPos(pa); break;
}
case 0:
{
sum = a.coef + b.coef;
if (sum)//系数非0,更改Pa的系数,对地址操作!
{
pa->data.coef=sum; prev = pa;//a.coef=sum错
}
else//系数为0,删除pa所指结点,同时更新pa(之后统一),prev
{
DelFirst(prev, &pa); FreeNode(pa);
if (pa == GetLast(*pPb))pPb->tail = prev;//注意尾指针所指结点可能被删除了
//及时更改尾指针
}
DelFirst(hb, &q);FreeNode(q);//删除Pb当前结点
pa = NextPos(prev); pb = NextPos(hb); break;
}
case 1://a的指数大,将多项式Pb当前结点插入Pa当前结点之前
{
DelFirst(hb, &q);
InsFirst(prev, q);
pb = NextPos(hb); pa = NextPos(pa);
}
}
}
if (pb)
{
Append(pPa, pb);//注意Append函数和InsFirst函数的区别
pPa->tail = pPb->tail;
}
FreeNode(hb);
}
5.辅助函数
5.1建立新结点
//1.将p所指结点的数据元素设置为e
void SetCurElem(Link p, ElemType e)
{
p->data.coef = e.coef;
p->data.expn = e.expn;
}
//2.用指针p承接动态分匹配的结点的地址,并将数据元素设置为e
Status MakeNode(Link* pp, ElemType e)
{
*pp = (Link)malloc(sizeof(LNode));
if (!*pp)return ERROR;
SetCurElem(*pp, e);
(*pp)->next = NULL;
return OK;
}
5.2建立带头结点的链表(此算法中是多项式)
//3.建立带头结点的链表(多项式)
Status InitPolyn(Polynomial* pP)
{
ElemType e = { 0.0,-1 };
MakeNode(&pP->head, e);
if (!pP->head)return ERROR;
pP->tail = pP->head;//tial是尾指针,初始化
return OK;
}
5.3.建立完整的多项式(输入)
//4.建立完整的链表
Status CreatePolyn(Polynomial* pP)
{
InitPolyn(pP);
Link p;
ElemType e;
int i, n;
printf("enter the number of Polyn:\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("enter coef,expn:\n");
scanf("%f,%d", &e.coef, &e.expn);
MakeNode(&p, e);//建立新结点
if (!p)return ERROR;
pP->tail->next = p;
pP->tail = p;//更新尾指针
}
return OK;
}
5.4打印多项式
//5.打印多项式
void PrintPolyn(Polynomial P)
{
Link p, h = GetHead(P);
p = NextPos(h);
int k = 0;//表示项的位置
ElemType e;
while (p)
{
e = GetCurElem(p);
printf("%dth %5.2fx[%d]\n", ++k, e.coef, e.expn);
p = NextPos(p);
}
printf("--------Print finished-------");
}
5.5其他简单函数
//7.获得头指针
Position GetHead(Polynomial P)
{
return P.head;
}
//8.获得尾指针
Position GetLast(Polynomial P)
{
return P.tail;
}
//9.指针p后移一位
Position NextPos(Link p)
{
return p->next;
}
//10.获得当前数据元素
ElemType GetCurElem(Link p)
{
return p->data;
}
//11.比较指数大小
int cmp(ElemType a, ElemType b)
{
return(a.expn == b.expn ? 0 : (a.expn > b.expn ? 1 : -1));
}
//12.删除指针h所指结点的后一个结点
void DelFirst(Link h, Link* pq)
{
*pq = NextPos(h);
h->next = NextPos(*pq);
}
//13.指针s所指结点插入p所指结点后
void InsFirst(Link p, Link s)
{
s->next = NextPos(p);
p->next = s;
}
//14.将指针p所指结点(及之后的结点)链接在多项式后
void Append(Polynomial* pP, Link p)
{
pP->tail->next = p;
}
//15.释放指针p所指结点内存
void FreeNode(Link p)
{
free(p);
}
说明
这个是《数据结构(C语言版)》严蔚敏里的算法,C代码实现。学习记录p43