多项式合并(C语言实现)

0.前言

最近放假在家无事,就想想多学学编程底层的知识,就买了一本数据结构来看看,这是我见过比高数,理力更蛋疼的课程了。书上就给了源代码,也没有详细介绍算法知识。合并算法也是搞了好久才懂得。

1.算法介绍

/*多项式合并算法

  1. 1.首先设计三个指针变量:pre、qa和qb,其中pre永远指向合多项式链表的尾节点,qa,qb分别从多项式的pa和pb链表的首项开始扫描
  2. 比较qa和qb所指节点指数域的值,可能出现下列三种情况之一
  3. (1)qa->exp大于qb->exp,qa继续向后扫描
  4. (2)qa->exp等于qb->exp,则系数相加。若相加结果为0,将结果放入qa->coef中,并删除qb所指节点,否则同时删除qa和qb所指的节点,然后qa,qb继续向后扫描
  5. (3)qa->exp小qb->exp,将qb节点插入到qa所指节点之前,然后qb继续向后扫描
  6. 2.扫描过程一直到qa或者qb有一个为空为止,然后将有剩余节点的链表连接到和多项式链表的尾部。
    */

#include  //多项式的合并 struct Ploy {
    int copf;//系数
    int   expn;//指数
    struct Ploy *next; };

Ploy* create_ploy() {
    Ploy *ploy=(Ploy*)malloc(sizeof(Ploy));
    if(NULL==ploy)
    {
        printf("malloc error.\n");
        return NULL;
    }

//    bzero(ploy,sizeof(Ploy)); //    memset(ploy,sizeof(Ploy));
    ploy->copf=10;
    ploy->expn=10;
    ploy->next=NULL;
    return ploy; }

//将最新节点插入最后一个位置 void add_ploy_item(Ploy *ploy,int copf,int expn) {
    Ploy *p=(Ploy*)malloc(sizeof(Ploy));
    if(NULL==p)
    {
        return;
    }
    p->copf=copf;
    p->expn=expn;
    p->next=NULL;
    while(NULL!=ploy->next)
    {
        ploy=ploy->next;
    }
    ploy->next=p; }

void display_item(Ploy *ploy) {
    if(NULL==ploy)
    {
        printf("ploy is null.\n");
        return;
    }
    while(NULL!=ploy->next)
    {
        printf("%dx^%d+",ploy->copf,ploy->expn);
        ploy=ploy->next;
    }
    //便利到最后一个节点时
    printf("%dx^%d.\n",ploy->copf,ploy->expn); }

//多项式合并 /*多项式合并算法  *
1.首先设计三个指针变量:pre、qa和qb,其中pre永远指向合多项式链表的尾节点,qa,qb分别从多项式的pa和pb链表的首项开始扫描
*   比较qa和qb所指节点指数域的值,可能出现下列三种情况之一  *1)qa->exp大于qb->exp,qa继续向后扫描  *2)qa->exp等于qb->exp,则系数相加。若相加结果为0,将结果放入qa->coef中,并删除qb所指节点,否则同时删除qa和qb所指的节点,然后qa,qb继续向后扫描
*3)qa->exp小qb->exp,将qb节点插入到qa所指节点之前,然后qb继续向后扫描  * 2.扫描过程一直到qa或者qb有一个为空为止,然后将有剩余节点的链表连接到和多项式链表的尾部。
*/ Ploy* ployadd(Ploy *pa,Ploy *pb) {
    //q为了节点删除的辅助变量.pre是一个临时变量,总是指着和多项式链表的尾端
    Ploy *pre,*qa,*qb,*q;
    qa=pa;
    qb=pb;
    pre=pa;
    while(qa&&qb)
    {
        //qa->exp大于qb->exp,qa继续向后扫描
       if(qa->expn>qb->expn)
       {
           pre=qa;
           qa=qa->next;
       }
       else
       {
           /*
            * qa->exp等于qb->exp,则系数相加。若相加结果为0,将结果放入qa->coef中,
            * 并删除qb所指节点,否则同时删除qa和qb所指的节点,然后qa,qb继续向后扫描
            */
           if(qa->expn==qb->expn)
           {
               int sum=qa->copf+qb->copf;
               if(0!=sum)
               {
                   qa->copf=sum;
                   pre=qa;

               }
               //如果合并后为0
               else
               {
                   pre->next=qa->next;
                   qa->copf=0;
               }
               qa=pre->next;
               q=qb;
               qb=qb->next;
               q->copf=0;
           }
           //qa->exp小于qb->exp,将qb节点插入到qa所指节点之前,然后qb继续向后扫描
            else
           {
               //pre可能原来指向别的数据。prb肯定一直都在qa上,所以先把qb接到qa上
               pre->next=qb;//保存qb节点,将qb节点接到pa处,pa,pb 轮换着来的
               //将qb插入到qa的上一个节点
               pre=qb;
               qb=qb->next;
               pre->next=qa;//qa再赋给qb
           }
       }
     printf("\n");
     printf("pre:");
     display_item(pre);
     printf("pa:");
     display_item(pa);
     printf("pb:");
     display_item(pb);
     printf("\n");
    }
    if(qb)
    { //        pre=(*Ploy)malloc(sizeof(Ploy));
        pre->next=qb;
    }
    return pa; }

int main(int argc, char *argv[]) {
    Ploy *pl=NULL;
    pl=create_ploy();
    add_ploy_item(pl,1,9);
    add_ploy_item(pl,1,7);
    add_ploy_item(pl,2,5);
    display_item(pl);
    Ploy *p2=create_ploy();
    add_ploy_item(p2,3,9);
    add_ploy_item(p2,1,8);
    add_ploy_item(p2,2,6);
     add_ploy_item(p2,2,5);
    display_item(p2);
    Ploy *p3=ployadd(pl,p2);
    display_item(p3);
    return 1; }

2.细节解析

多项式合并(C语言实现)_第1张图片多项式合并(C语言实现)_第2张图片
这里两幅图是分别pre->next=qb;这句话有没有注释的区别。从这里我们可以看到这个算法遇到pb比pa大,就将pb的后面节点移到pa后。如果pre->next=qb这句注释的话,那么就无法实现pb将值嵌入pa中了。

你可能感兴趣的:(Qt)