zoukankan      html  css  js  c++  java
  • 线性表->应用->一元多项式

    文字描述
      在数学上,一个一元多项式可以按升幂写成如下形式。 

      
      它由n+1个系数唯一确定。因此,在计算机里,可以用一个线性表P来表示,P中每一项的指数i隐含在其系数pi的序号里。
       
      但是在通常的应用中,多项式的次数可能很高且变化很大,使得顺序存储结构的最大长度很难确定。比如如下多项式,就要用一个长度为20001的线形表来表示,表中仅有3个非零元素,这种会极其浪费内存空间。
       
      针对上面这种情况,可以在线形表中只存放非零的元素,每个元素有两个数据项(系数项和指数项),如下。这便可唯一确定多项式Pn(x)。在最坏情况下,n+1(=m)个系数都不为零,则比只存储每项系数的方案要多存储一倍的数据。
     
    示意图
     


    算法分析
      多项式的相加过程和之前讨论的归并两个有序表的过程很类似。时间复杂度同单向链表的归并算法相同。
     
    代码实现

      1 //
      2 // Created by lady on 19-2-17.
      3 //
      4 
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 
      8 typedef struct {
      9     float coef;//系数
     10     int expn;//指数
     11 }term, ElemType;
     12 
     13 typedef struct LNode{//结点类型
     14     ElemType e;
     15     struct LNode *next;
     16 }*Link;
     17 
     18 typedef struct {//链表类型
     19     Link head;//指向线性链表中的头结点
     20 }LinkList;
     21 
     22 typedef LinkList polynomial;//用带表头结点的有序链表表示多项式
     23 
     24 //构造一个空的线性链表L
     25 static int InitList(LinkList *L)
     26 {
     27     if(L == NULL)
     28         return -1;
     29     Link p = (Link)malloc(sizeof(struct LNode));
     30     p->next = NULL;
     31     L->head = p;
     32     return 0;
     33 }
     34 
     35 //返回链表L的头结点
     36 static Link GetHead(LinkList *L){
     37     if(L==NULL){
     38         return NULL;
     39     }
     40     return L->head;
     41 }
     42 
     43 //设置p结点的数据元素值为e
     44 static void SetCurElem(Link p, ElemType e)
     45 {
     46     p->e = e;
     47     return 0;
     48 }
     49 
     50 //返回线性表L中第1个与e满足函数fun判定关系的元素的位置,并用q指示其结点地址值
     51 static int LocateElem(LinkList *L, ElemType e, Link *q, int (*fun)(term, term))
     52 {
     53     Link p = L->head->next;
     54     (*q) = L->head;
     55     while(p){
     56         if(fun(p->e, e) == 0){
     57             (*q) = p;
     58             return 0;
     59         }
     60         (*q) = p;
     61          p = p->next;
     62     }
     63     return -1;
     64 }
     65 
     66 //已知h指向线性表的头结点,将s所指结点插入在第一个结点之前
     67 static int InsFirst(Link *h, Link *s)
     68 {
     69     if(h==NULL || s==NULL){
     70         return -1;
     71     }
     72     if(*h == NULL || *s == NULL){
     73         return -1;
     74     }
     75     (*s)->next = (*h)->next;
     76     (*h)->next = (*s);
     77     return 0;
     78 }
     79 
     80 //创建新的结点,其地址值为*p, 结点值为e
     81 static int MakeNode(Link *p, ElemType e)
     82 {
     83     if(p==NULL){
     84         return -1;
     85     }
     86     if(((*p) = (Link)malloc(sizeof(struct LNode))) == NULL){
     87         return -1;
     88     }
     89     (*p)->next = NULL;
     90     (*p)->e = e;
     91     return 0;
     92 }
     93 
     94 //返回链表L中p结点的后继
     95 static Link NextPos(LinkList *L, Link p)
     96 {
     97     if(L == NULL || p==NULL){
     98         return NULL;
     99     }
    100     return p->next;
    101 }
    102 
    103 //返回结点p的数据元素值
    104 static  ElemType GetCurElem(Link p)
    105 {
    106     return p->e;
    107 }
    108 
    109 //释放结点及其一系列后面的结点的存储空间
    110 static void FreeNode(Link p)
    111 {
    112     Link q;
    113     while(p){
    114         q = p;
    115         p = p->next;
    116         free(q);
    117     }
    118     return;
    119 }
    120 //已知h指向线性链表的头结点,删除链表中的第一个结点并以求返回
    121 static int DelFirst(Link *h, Link *q)
    122 {
    123     if(h==NULL || q==NULL){
    124         return -1;
    125     }
    126     if(*h == NULL || *q == NULL){
    127         return -1;
    128     }
    129     (*q) = (*h)->next;
    130     (*h)->next = (*q)->next;
    131     (*q)->next = NULL;
    132     return 0;
    133 }
    134 
    135 //返回1-链表为空, 返回0-链表非空
    136 static int ListEmpty(LinkList *L)
    137 {
    138     if(L->head->next == NULL){
    139         return 1;
    140     }else{
    141         return 0;
    142     }
    143 }
    144 
    145 //将指针s所指的一串结点连接到线性链表L的最后一个结点
    146 static int Append(LinkList *L, Link *s)
    147 {
    148     if(L == NULL || s==NULL || *s==NULL){
    149         return -1;
    150     }
    151     Link p = L->head->next;
    152     Link q = L->head;
    153     while(p){
    154         q = p;
    155         p = p->next;
    156     }
    157     q->next = (*s);
    158     return 0;
    159 }
    160 
    161 /*
    162  * 依a的指数值<(或=)(或>)b的指数值,分别返回-1、0和+1
    163  */
    164 static int cmp(term a, term b)
    165 {
    166     if(a.expn<b.expn){
    167         return -1;
    168     }else if(a.expn == b.expn){
    169         return 0;
    170     }else{
    171         return 1;
    172     }
    173 }
    174 
    175 
    176 
    177 //输入m项的系数和指数,建立表示一元多项式的有序链表P
    178 static void CreatPolyn(polynomial *P, int m, char note[]){
    179     printf("创建多项式%s!
    ", note);
    180     int i = 0;
    181     Link h;
    182     Link s;
    183     Link q;
    184     ElemType e;
    185     InitList(P);
    186     h = GetHead(P);
    187     e.coef = -1;
    188     e.expn = -1;
    189     SetCurElem(h, e);//设置头结点的数据元素
    190     for(i=1; i<=m; i++){//依次输入m个非零项
    191         printf("输入第%d个非0项(系数,指数):", i);
    192         scanf("%f,%d[^\n]", &e.coef, &e.expn);
    193         if(LocateElem(P, e, &q, cmp)<0){//如果当前链表中不存在该指数项
    194             if(MakeNode(&s, e)==0){//生成结点并插入链表
    195                 InsFirst(&q, &s);
    196             }
    197         }
    198     }
    199     return ;
    200 }
    201 
    202 //打印一元多项式
    203 static void PrintPolyn(polynomial P, char note[])
    204 {
    205     printf("打印输出一元多项式%s: ", note);
    206     Link p = P.head->next;
    207     while(p){
    208         printf("%.2fx^%d", p->e.coef, p->e.expn);
    209         if(p->next){
    210             printf("+");
    211         }
    212         p = p->next;
    213     }
    214     printf("
    ");
    215 }
    216 
    217 //多项式加法:Pa=Pa+Pb,利用两个多项式的结点构成"和多项式"
    218 static void AddPolyn(polynomial *Pa, polynomial *Pb, char note[])
    219 {
    220     printf("多项式相加,%s!
    ", note);
    221     //ha和hb分别指向Pa和Pb的头结点
    222     Link ha = GetHead(Pa);
    223     Link hb = GetHead(Pb);
    224     //qa和qb分别指向Pa和Pb中的当前结点
    225     Link qa = NextPos(Pa, ha);
    226     Link qb = NextPos(Pb, hb);
    227     ElemType a;
    228     ElemType b;
    229     ElemType e;
    230     while(qa && qb){//qa和qb均非空
    231         //a和b为两个表中当前的比较元素
    232         a = GetCurElem(qa);
    233         b = GetCurElem(qb);
    234         switch(cmp(a,b)){
    235             case -1://a<b,多项式Pa中当前结点的指数小
    236                 ha = qa;
    237                 qa = NextPos(Pa, qa);
    238                 break;
    239             case 0://a==b,两者的指数值相等
    240                 e.expn = a.expn;
    241                 e.coef = a.coef+b.coef;
    242                 if(e.coef!=0.0){//修改多项式Pa中当前结点的系数值
    243                     SetCurElem(qa, e);
    244                     ha = qa;
    245                 }else{
    246                     DelFirst(&ha, &qa);
    247                     FreeNode(qa);
    248                 }
    249                 DelFirst(&hb, &qb);
    250                 FreeNode(qb);
    251                 qb = NextPos(Pb, hb);
    252                 qa = NextPos(Pa, ha);
    253                 break;
    254             case 1://a>b,多项式Pb中当前结点的指数小
    255                 DelFirst(Pb, &qb);
    256                 qb->next = NULL;
    257                 InsFirst(&ha, &qb);
    258                 qb = NextPos(Pb, hb);
    259                 qa = NextPos(Pa, ha);
    260                 break;
    261         }
    262     }
    263     if(ListEmpty(Pb)==0){//链接Pb中剩余结点
    264         Append(Pa, &qb);
    265     }
    266     FreeNode(hb);//释放Pb的头结点
    267     return ;
    268 }
    269 
    270 int main(int argc, char *argv[])
    271 {
    272     polynomial A;//7+3x+9x^8+5x^17
    273     polynomial B;//8x+22x^7-9x^8
    274 
    275     CreatPolyn(&A, 4, "A");
    276     PrintPolyn(A, "A");
    277 
    278     CreatPolyn(&B, 3, "B");
    279     PrintPolyn(B, "B");
    280 
    281     AddPolyn(&A, &B, "A=A+B");
    282     PrintPolyn(A, "A");
    283     return 0;
    284 }
    线性表的应用(一元多项式)

    代码运行

    /home/lady/CLionProjects/untitled/cmake-build-debug/untitled
    创建多项式A!
    输入第1个非0项(系数,指数):7,0
    输入第2个非0项(系数,指数):3,1
    输入第3个非0项(系数,指数):9,8
    输入第4个非0项(系数,指数):5,17
    打印输出一元多项式A: 7.00x^0+3.00x^1+9.00x^8+5.00x^17
    创建多项式B!
    输入第1个非0项(系数,指数):8,1
    输入第2个非0项(系数,指数):22,7
    输入第3个非0项(系数,指数):-9,8
    打印输出一元多项式B: 8.00x^1+22.00x^7+-9.00x^8
    多项式相加,A=A+B!
    打印输出一元多项式A: 7.00x^0+11.00x^1+22.00x^7+5.00x^17
    
    Process finished with exit code 0
  • 相关阅读:
    一般处理程序页ashx 序列化 Json数组
    SQL server 分页
    MySQL 分页
    获取网站的BaseURL
    java学习书籍推荐
    查询并关闭指定端口进程
    ettercap使用
    MS10-046漏洞利用
    MS12-020漏洞利用
    入侵安卓手机
  • 原文地址:https://www.cnblogs.com/aimmiao/p/10405860.html
Copyright © 2011-2022 走看看