1 //2_4.h
2 /**3 《数据结构(C语言版)》 Page 374 ....为此,从实际应用角度出发重新定义线性链表及其基本操作....5 */
6 /**7 author:zhaoyu8 9 date:2016-6-610 note:realize my textbook <>11 */
12 #ifndef _2_4_H_13 #define _2_4_H_
14 #include "head.h"
15 typedef struct{//项的表示,多项式的项作为LinkList的数据元素
16 float coef;//系数
17 int expn;//指数
18 }term, ElemType;//两个类型名:term用于本ADT,ElemType为LinkList的数据对象名
19 typedef structLNode{20 ElemType data;21 struct LNode *next;22 }*Link, *Position;23 typedef struct{//链表类型
24 Link head, tail;//分别指向线性链表中的头结点和最后一个结点
25 int len;//指示线性链表中数据元素的个数
26 }LinkList;27 typedef LinkList polynomial;//用带表头结点的有序链表表示多项式
28
29 intcmp(term a, term b)30 {31 //依据 a 的指数值 ) b 的指数值 ,返回 -1 ,0, +1
32 if(a.expn
41 {42 return 1;43 }44 }45 Status InitList(LinkList &L)46 {47 //构造一个空的线性表L
48 L.head = (Link)malloc(sizeof(structLNode));49 L.head->data.coef = 0.0;50 L.head->data.expn = -1;51 L.head->next =NULL;52 L.tail = L.head->next;53 L.len = 0;54 }55 Position GetHead(LinkList L)56 {57 //返回线性链表 L 中头结点的位置
58 returnL.head;59 }60 Status SetCurElem(Link &p, ElemType e)61 {62 //已知 p 指向线性链表中的一个结点,用 e 更新 p 所指结点中数据元素的值
63 p->data.coef =e.coef;64 p->data.expn =e.expn;65 returnOK;66 }67 Status LocateElem(LinkList L, ElemType e, Position &q, Status (*compare)(ElemType, ElemType))68 {69 //若有序链表 L 中存在与 e 满足判定函数 compare() 取值为 0 的函数70 //则 q 指示 L 中第一个值为 e 的结点的位置,并返回 TRUE;否则 q 指示71 //第一个与 e 满足compare() 取值>0的元素的前驱的位置,并返回FLASE
72 Link temp = L.head->next;73 while (temp !=NULL)74 {75 if (0 == (* compare)(temp->data, e))76 {77 q =temp;78 returnTRUE;79 }80 temp = temp->next;81 }82 temp =L.head;83 while (temp->next !=NULL)84 {85 if ((* compare)(temp->next->data, e) > 0)86 {87 q =temp;88 returnFALSE;89 }90 temp = temp->next;91 }92 q =temp;93 returnFALSE;94 }95 Status MakeNode(Link &p, ElemType e)96 {97 //分配由 p 指向的值为 e 的结点,并返回 OK;若分配失败,则返回 ERROR
98 p = (Link)malloc(sizeof(structLNode));99 if (!p)100 {101 returnERROR;102 }103 p->data.coef =e.coef;104 p->data.expn =e.expn;105 p->next =NULL;106 returnOK;107 }108 Status InsFirst(Link &h, Link &s)109 {110 //已知 h 指向线性链表的头结点,将 s 所指节点插入在第一个结点之前
111 if (NULL ==h)112 {113 returnERROR;114 }115 else
116 {117 s->next = h->next;118 h->next =s;119 }120 returnOK;121 }122 ElemType GetCurElem(Link p)123 {124 //已知 p 指向线性链表中的一个节点,返回 p 所指结点中数据元素的值
125 if (p !=NULL)126 {127 return p->data;128 }129 else
130 {131 exit(ERROR);132 }133 }134 /**135 My Code136 */
137 Position NextPos(LinkList L, Link p)138 {139 //已知 p 指向线性链表 L 中的一个节点,返回 p 所指结点140 //的直接后继的位置,若无后继,返回 NULL
141 Link q =L.head;142 while (q->next !=NULL)143 {144 if(q ==p)145 {146 return p->next;147 }148 q = q->next;149 }150 returnNULL;151 }152 Status DelFirst(Link &h, Link &q)153 {154 //已知 h 指向线性链表的头结点,删除链表中的第一个节点并以 q 返回
155 if (h ==NULL)156 {157 returnERROR;158 }159 q = h->next;160 h->next = q->next;161 q->next =NULL;162 returnOK;163 }164 Status FreeNode(Link &p)165 {166 //释放 p 所指节点
167 p = NULL;//便于回收???释放后再次使用
168 free(p);169 }170 Status ListEmpty(LinkList L)171 {172 //若线性链表 L 为空,则返回 TRUE,否则返回 FALSE
173 if (L.head->next ==NULL)174 {175 returnTRUE;176 }177 else
178 {179 returnFALSE;180 }181 }182 Status Append(LinkList &L, Link &s)183 {184 //将指针 s 所指(彼此以指针相链)的一串结点185 //链接在线性链表 L 最后一个结点
186 Link q =L.head;187 while (q->next !=NULL)188 {189 q = q->next;190 }191 q->next =s;192 int cnt = 0;193 Link temp =s;194 while (temp !=NULL)195 {196 cnt++;197 if (NULL == temp->next)198 {199 L.tail = temp;//注意更新尾指针
200 }201 temp = temp->next;//注意这一句要放在最后,否则可能访问非法内存
202 }203
204 L.len +=cnt;205 //注意要根据这一串结点长度增加链表长度
206 returnOK;207 }208 voidPrintPolyn(polynomial P)209 {210 Link temp = P.head->next;211 while (temp !=NULL)212 {213 printf("%.1f\t", temp->data.coef);214 temp = temp->next;215 }216 printf("\n");217 temp = P.head->next;218 while (temp !=NULL)219 {220 printf("%d\t", temp->data.expn);221 temp = temp->next;222 }223 printf("\n");224 }225 /**226 algorithm 2.22227 */
228 void CreatPolyn(polynomial &P, intm)229 {230 //输入 m 项的系数和指数,建立表示一元多项式的有序链表 P
231 InitList(P);232 Link h =GetHead(P), s, q;233 ElemType e;234 e.coef = 0.0;235 e.expn = -1;236 SetCurElem(h, e);//设置头结点中的数据元素
237 for (int i = 1; i <= m; i++)238 {//依次输入 m 个非零项
239 scanf("%f%d", &e.coef, &e.expn);240 if (!LocateElem(P, e, q, (*cmp)))241 {//当前链表中不存在该指数项
242 if(MakeNode(s, e))243 {244 InsFirst(q, s);245 }246 }247 }248 }//CreatePolyn
249 /**250 algorithm 2.23251 */
252 void AddPolyn(polynomial &Pa, polynomial &Pb)253 {254 //多项式加法:Pa = Pa + Pb,利用两个多项式构成和多项式
255 Link ha =GetHead(Pa);256 Link hb = GetHead(Pb);//pa 和 pb 分别指向 Pa 和 Pb 的头结点
257 Link qa =NextPos(Pa, ha);258 Link qb = NextPos(Pb, hb);//qa 和 qb 分别指向 Pa 和 Pb 中当前节点
259 while (qa && qb)//qa 和 qb均非空
260 {261 ElemType a =GetCurElem(qa);262 ElemType b = GetCurElem(qb);//a、b为两表中当前比较元素
263 switch ((*cmp)(a, b))264 {265 case -1://多项式 Pa 中当前节点的指数值小
266 {267 ha =qa;268 qa = NextPos(Pa, qa);//printf("%d\n", qa->data.expn);
269 break;270 }271 case 0://两者的指数值相等
272 {273 ElemType S = {a.coef +b.coef, a.expn};274 if(0 !=S.coef)275 {//修改多项式 Pa 中当前节点
276 SetCurElem(qa, S);277 ha =qa;278 }279 else
280 {//删除多项式中 Pa 当前节点
281 DelFirst(ha, qa);282 FreeNode(qa);283 }284 DelFirst(hb, qb);285 FreeNode(qb);286 qa =NextPos(Pa, ha);287 qb =NextPos(Pb, hb);288 break;289 }290 case 1://多项式 Pb 当前结点指数值小
291 {292 DelFirst(hb, qb);293 InsFirst(ha, qb);294 qb =NextPos(Pb, hb);295 ha =NextPos(Pa, ha);296 break;297 }298 }//switch
299 }//while
300 if (!ListEmpty(Pb))301 {302 Append(Pa, qb);//链接 Pb 中剩余结点
303 }304 FreeNode(hb);//释放 Pb 的头结点
305 }//AddPolyn
306 #endif