学习记录,仅供参考,希望可以指出错误
根据带头结点的线性链表改编,即elemtype也变成了struct结构
#include<stdio.h> #include<stdlib.h> //改由带头结点的线性链表 #define OK 1 #define ERROR 0 typedef int status; typedef struct { float coef;//系数 int expn;//指数 }term,elemtype; typedef struct lnode{ elemtype data; struct lnode *next; }*link,*position; typedef struct{ link head,tail; int len; }linklist; typedef linklist polynomial; status makenode(link &p,elemtype e){//分配由p指向的值为e的结点,并返回OK,若分配失败返回ERROR p=new lnode; p->data=e; p->next=NULL; if(p) return OK; else return ERROR; } void freenode(link &p){//释放p所指向的结点 free(p); p=NULL; } status initlist(linklist &l){//构造空的线性链表l(空表里还是有一个结点的 link p=new lnode; l.len=0; l.head=l.tail=p; p->next=NULL; if(p) return OK; return ERROR; } position gethead(linklist l){//返回l中头结点的位置 return l.head; } position getlast(linklist l){//返回l中最后一个结点的位置 return l.tail; } void clearlist(linklist &l){//将线性链表l重置为空表,并释放原链表的结点空间 link p,q; p=l.head; while(p){ q=p->next; free(p); p=q; } p=new lnode; l.head=l.tail=p; p->next=NULL; l.len=0; } void destorylist(linklist &l){//销毁线性链表l,l不再存在 clearlist(l); free(l.head); l.head=l.tail=NULL; } void insfirst(linklist &l,link h,link s){//已知h指向线性链表的头结点,将s所指结点插入在第一个结点之前(头!=一 s->next=h->next; h->next=s; if(h==l.tail) l.tail=h->next; l.len++; } status delfirst(linklist &l,link h,link &q){//已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回 q=h->next; if(q){//如果链表非空 h->next=q->next; q->next=NULL; if(!h->next) l.tail=h; l.len--; return OK; } return ERROR; } void append(linklist &l,link s){//将指针s所指(彼此以指针相链)的一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新的尾结点 int inc=0; l.tail->next=s; while(s){//link的元素个数 l.tail=s; s=s->next; inc++; } l.len=l.len+inc; } void remove(linklist &l,link &q){//删除线性链表L中的尾结点并以q返回,改变链表L的尾结点指向新的尾结点 link p=gethead(l); while(p->next!=l.tail&&p->next!=NULL){//找到要某个结点的前一个 p=p->next; } q=p->next; l.tail=p; l.len--; } position priorpos(linklist l,link p){//已知p指向l中的一个结点,返回p所指结点的前驱,若无返回null link q=gethead(l); while(q->next!=p&&q->next!=NULL){ q=q->next; } if(q->next==NULL) return NULL; return q; } position nextpos(link p){//已知p指向l中的一个结点,返回p所指结点的后继,若无返回null if(!p) return NULL; return p->next; } void insbefore(linklist &l,link &p,link &s){//已知p指向l中的一个结点,将s所指的结点插入在p所指的结点之前,并修改指针p指向新插入的结点 link q=priorpos(l,p);//找p的前趋 if(!q) q=gethead(l);//如果没有前趋 s->next=p; q->next=s; p=s; l.len++; } void insafter(linklist &l,link &p,link s){//已知p指向l中的一个结点,将s所指的结点插入在p所指的结点之后,并修改指针p指向新插入的结点 if(p==l.tail) l.tail=s;//如果p是最后一个结点,则修改最后一个结点为s s->next=p->next; p->next=s; p=s; l.len++; } void setcurelem(link &p,elemtype e){//已知p指向线性链表中的一个结点,用e更新结点中数据元素的指 p->data=e; } elemtype getcurelem(link p){//已知p指向线性链表中的一个结点,返回他的值 return p->data; } int listempty(linklist l){//判断是否为空 if(l.len==0) return 0; else return l.len; } int listlength(linklist l){//返回元素个数 return l.len; } int locatepos(linklist l,int i,link &p){//返回p所指示l中第i个结点的位置并返回OK,否则返回ERROR if(i<0||i>l.len) return 0; p=l.head; int count=0; while(count<i){ count++; p=p->next; } return 1; } int xishuk(elemtype e,elemtype k){//如果不存在该系数,返回0 if(e.expn==k.expn) return 0; if(e.expn<k.expn) return -1; return 1; } status locateelem(linklist l,elemtype e,position &q,int (*compare)(elemtype,elemtype)){//返回l中第一个与e满足函数compare判定关系的元素的位置,若不存在返回Null link p=gethead(l); while(p->next){ p=nextpos(p); if(!(*compare)(p->data,e)){q=p; return OK;}//返回第一个系数为k的 } q=p; return ERROR;//说明没有满足的 } void visit1(elemtype e){//输出所有系数 printf("%f ",e.coef); } void listtraverse(linklist l,void (*visit)(elemtype)){//依次对L的每个元素调用函数visit,一旦visit失败则操作失败 link p=gethead(l)->next; while(p){ visit(p->data); p=nextpos(p); } printf("\n"); } status listinsert(linklist &l,int i,elemtype e){//在带头结点的单链线性表l的第i个元素之前添加元素e link p,q; if(!locatepos(l,i-1,p)) return ERROR; if(!makenode(q,e)) return ERROR; insfirst(l,p,q); return OK; } void scanf_xxlb(linklist &l){ printf(" num is:"); int num; scanf("%d",&num); printf("\n to:\n"); for(int i=1;i<=num;i++){ elemtype e; scanf("%f",&e.coef); scanf("%d",&e.expn); listinsert(l,i,e); } } void printf_xxlb(linklist l){ printf("\n printf:\n"); link p=gethead(l); for(int i=0;i<l.len;i++){ p=nextpos(p); printf("%fx^%d ",p->data.coef,p->data.expn); } printf("\n"); } //status locateelem(linklist l,elemtype e,position &q,int(*compare)(elemtype,elemtype)){}//在上方 void printpolyn(polynomial p){//打印输出一元多项式 printf("\n printf:\n"); link q=gethead(p); for(int i=0;i<p.len;i++){ q=nextpos(q); printf("%fx^%d ",q->data.coef,q->data.expn); } printf("\n"); } int sortcom(elemtype a,elemtype b){// if(a.expn < b.expn)return 1; if(a.expn == b.expn)return -1; return 0; } status orderinsert(linklist &l,elemtype e,int(*compare)(elemtype,elemtype)){//按照有序判定函数compare()的约定,将值为e的结点插入到有序链表l的合适位置上 link q; makenode(q,e); for(int i=1;i<=l.len;i++){ link p; locatepos(l,i,p); switch(sortcom(e,p->data)){ case 1://找到了 insfirst(l,priorpos(l,p),q); return OK; case -1://找到了指数相同的,就改变系数 e.coef=e.coef+p->data.coef; setcurelem(p,e); return ERROR; } } link last=getlast(l);//没找到,添加到末尾 insafter(l,last,q); return OK; } status sortpolyn(polynomial &p){//按照指数排序 if(p.len<2) return ERROR;//如果小于2,则不用排序 link hq=gethead(p); link tq=nextpos(hq);//这时候tq是第一个 while(nextpos(tq)){//如果tq的下一个不为空 link xq=tq; link nextp=nextpos(tq); int a=getcurelem(nextp).expn;//当前 int b=getcurelem(tq).expn;//当前的上一个 int sign=0; while(a<=b){//如果当前的指数小于当前的上一个 sign++;//标记不为0了 link del;delfirst(p,tq,del);//删除当前 if(a==b){ elemtype e;e.coef=del->data.coef+tq->data.coef;e.expn=a; tq->data=e; nextp=tq; tq=priorpos(p,nextp); }else{ insfirst(p,priorpos(p,tq),del);//把当前添加到上一个的上一个的后面 nextp=del;//修改当前 } tq=priorpos(p,nextp);//修改当前的上一个 a=getcurelem(nextp).expn;//当前 b=getcurelem(tq).expn;//当前的上一个 } if(sign==0) tq=nextpos(xq);//如果标记为0,就说明没有进行排序 } return OK; } //算法2.22 void createpolyn(polynomial &p,int m){//输入m项的系数和指数,建立表示一元多项式的有序链表 //比如当输入n,6之后在输入m,6因为指数是相同的,所以m,6不会加入到队列(没设置自动合并 initlist(p); link h=gethead(p); elemtype e; e.coef=0.0;e.expn=-1; setcurelem(h,e); for(int i=1;i<=m;++i){ printf("输入:\n");scanf("%f",&e.coef);scanf("%d",&e.expn); link q; if(!locateelem(p,e,q,xishuk)){//如果不存在该指数项 link s; if(makenode(s,e)) insfirst(p,q,s); } //orderinsert(p,e,sortcom);插入的时候就自动按照指数进行操作了 //link s;makenode(s,e);append(p,s);sortpolyn(pa);//插完再排序 } } void destorypolyn(polynomial &p){//销毁一元多项式p clearlist(p); free(p.head); p.head=p.tail=NULL; } int polynlength(polynomial p){//返回一元多项式p中的项数 return p.len; } //算法2.23 void addpolyn(polynomial &pa,polynomial &pb){//加法,好像只能是他的qa和qb的指数呈上升,比如x+2x^3+3x^4,不能2x^3+x+3x^4 link ha=gethead(pa),hb=gethead(pb); link qa=nextpos(ha),qb=nextpos(hb);//qa是当前结点 while(qa&&qb){ elemtype a=getcurelem(qa),b=getcurelem(qb); switch(xishuk(a,b)){//判断b的结点的指数对于a的比较 case -1://多项式pa中当前结点的指数小 ha=qa;qa=nextpos(qa);break; case 0://两者指数相等 elemtype sum; sum.coef=a.coef+b.coef; sum.expn=a.expn; if(sum.coef!=0){ setcurelem(qa,sum);ha=qa;} else{ delfirst(pa,ha,qa);freenode(qa);} delfirst(pb,hb,qb);freenode(qb);qb=nextpos(hb); qa=nextpos(ha);break; case 1://多项式pb中当前结点的指数小 delfirst(pb,hb,qb);insfirst(pa,ha,qb); qb=nextpos(hb);ha=nextpos(ha);break; } } if(listempty(pb)) append(pa,qb); freenode(hb); } void subtractpolyn(polynomial &pa,polynomial &pb){//减法,根据上面的改编的 link ha=gethead(pa),hb=gethead(pb); link qa=nextpos(ha),qb=nextpos(hb);//qa是当前结点 while(qa&&qb){ elemtype a=getcurelem(qa),b=getcurelem(qb); switch(xishuk(a,b)){//判断b的结点的指数对于a的比较 case -1://多项式pa中当前结点的指数小 ha=qa;qa=nextpos(qa);break; case 0://两者指数相等,就进行计算 elemtype sum; sum.coef=a.coef-b.coef; sum.expn=a.expn; if(sum.coef!=0){ setcurelem(qa,sum);printf_xxlb(pa);ha=qa;} else{ delfirst(pa,ha,qa);freenode(qa);} delfirst(pb,hb,qb);freenode(qb);qb=nextpos(hb); qa=nextpos(ha);break; case 1://多项式pb中当前结点的指数小 elemtype e; e.coef=-b.coef; e.expn=b.expn; setcurelem(qb,e); delfirst(pb,hb,qb);insfirst(pa,ha,qb); qb=nextpos(hb);ha=nextpos(ha);break; } } if(listempty(pb)) append(pa,qb); freenode(hb); } polynomial multiplypolyn(polynomial &pa,polynomial &pb){//乘法 link ha=gethead(pa),hb=gethead(pb); link qa=nextpos(ha),qb=nextpos(hb);//qa是当前结点 polynomial pc; initlist(pc); while(qa){ elemtype a=qa->data; polynomial pd; initlist(pd); link qtb=qb; int i=1; while(qtb){ elemtype b=qtb->data; elemtype e; e.coef=a.coef*b.coef; e.expn=a.expn+b.expn; listinsert(pd,i,e);i++; qtb=nextpos(qtb); } addpolyn(pc,pd); qa=nextpos(qa); } return pc; } void main(){ polynomial pa; printf("*******************测试createpolyn\n"); createpolyn(pa,9); //printf("*******************测试createpolyn\n"); //createpolyn(pb,2); //addpolyn(pa,pb); //subtractpolyn(pa,pb); //polynomial pc=multiplypolyn(pa,pb); printf("*******************测试printpolyns\n"); printf_xxlb(pa); }