数据结构第二周笔记(6)——线性结构(慕课浙大版本--XiaoYu)

129 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

小白专场

image-20220629071856844

多项式的表示

image-20220629072141892

用链表进行表示
    数据结构设计
    typedef struct PolyNode *Polynomial;//将结构指针定义为一个新的类型叫做Polynomial
struct PolyNode{
    int coef;//系数
    int expon;//指数
    Polynomial link;//阈,作为指针指向下一个节点
}

程序框架搭建

int main()
{
    读入多项式1
    读入多项式2
    乘法运算并输出
    加法运算并输出
        
        return 0;
}
需要设计的函数:
    1.读一个多项式
    2.两多项式相乘
    3.两多项式相加
    4.多项式输出
   
    int main()
{
    Polynomial P1,P2,PP,PS;
    
    P1 = ReadPoly();
    P2 = ReadPoly();//P1,P2都是链表的结构的指针
    PP = Mult(P1,P2);//Mult是乘法运算,返回的也是一个结构的指针
    PrintPoly(PP);//由PrintPoly来输出多项式
    PS = Add(P1,P2);//加法运算 
    PrintPoly(PS);
    
    return 0;
}
​
如何读入多项式
    Polynomial ReadPoly()
{
    ....//先读整数再一对一的读入系数跟指数
        scanf("%d",&N);
    ....
        while(N--){//这是读入系数跟指数,放到c跟e里面
        scanf("%d %d",&c,&e);
        Attach(c,e,&Rear);//读的时候是通过指数递降的顺序来读取的,Rear是可以被改变的,Rear是指向目前为止多项式的最后一项
        }
}
//注意:我们是从左到右读入的,而且先读的是指数高的一项,要插到一个链表里面去,然后再读一对数再插进去,再形成一个节点
//再读一对系数指数,再插到多项式里面去,在链表里面也是指数递降的,应该插到原来结果的后面
​
Rear初始值是多少?
    两种处理方法:
    1.Rear初值为NULL(说明是刚开始的一个节点,这个时候需要申请节点,然后把Rear用NULL改为指向这个节点)
    在Attach函数中根据Rear是否为NULL做不同处理
    如果值不为NULL,因为从第二项开始Rear值就不为NULL了。这个时候直接把新的节点插到Rear的后面。这样的一种处理方式在Attach函数里面他必须判别Rear是NULL还是说不是NULL,因为这两者处理的程序是不一样的
    2.Rear指向一个空结点(程序时更简单)
    需要注意在最后的时候记得把这个空结点释放掉
    
    处理方法2的具体代码:
    void Attach (int c,int e,Polynomial*pRear)//Polynomial本身也是指针,所以这里的pRear实际是指针的指针(为什么这么做是因为C语言是函数常数直传递)
{
    Polynomial P;
    P = (Polynomial)malloc(sizeof(struct PolyNode));
    P -> coef = c;//对新结点赋值
    P -> expon = e;
    P -> link = NULL;
    (*pRear)->link = P;//指针指过去了
    *pRear = P;//修改pRear值,指到P那里去了
}

image-20220629084605937

image-20220629084915089

image-20220629085051166

处理方法2

image-20220629085848083

读入多项式的完整程序

Polynomial ReadPoly()
{
    Polynomial P,Rear,t;
    int c,e,N;
    
    scanf("%d",&N);
    P = (Polynomial)malloc(sizeof(struct PolyNode));//链表头空结点
    P -> link = NULL;
    Rear = P;
    while(N--){
        scanf("%d %d",&c,&e);
        Attach(c,e,&Rear)//将当前项插入多项式尾部
    }
    t = P;P = P -> link;free(t);//删除临时生成的头结点  t指向P,P指向P的link  
    return P;
}

image-20220629091612698

如何将两个多项式相乘

  1. 将当前乘法运算转换为加法运算
将P1当前项(ci,ei)乘P2多项式,再加到结果多项式里
t1 = P1;t2 = P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));P->link=NULL;//指向空结点的操作
Rear = P;
while(t2){
    Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
    t2 = t2->link;
}

2.逐项插入

将P1当前项(c1i,e1i)乘P2当前项(c2i,e2i),并插入到结果多项式中。关键是要找到插入位置
初始结果多项式可以由P1第一项乘P2获得(如上)
    
    具体代码如下
    Polynomial Mult(Polynomial P1,Polynomial P2)
{
    .......
    t1 = P1;t2 = P2;
    .......
    while(2){
        //先用P1的第一项乘以P2,得到P
        ........
    }
    t1 = t1->link;
    while(t1){
        t2 = P2;Rear = P;
        while(t2){
            e=t1->expon + t2->expon;//指数相加
            c=t1->coef*t2->coef;//系数相乘
            ......
            t2=t2->link;
        }
        t1=t1-<link;
    }
    ......
}

以上代码块中有三项省略号的地方需要解释,单独分别列出来在下方进行标记

第一处省略

Polynomial P,Rear,t1,t2,t;
int c,e;
​
if(!P1||!P2) return NULL;t1 = P1;t2 = P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));P->link = NULL;
Rear = P;

第二处

while(t1){
    t2 = P2;Rear = P;
    while(t2){
        e = t1->expon + t2->expon;
        c = t1->coef*t2->coef;
    while(Rear->link && Rear->link->expon>e)
        Rear = Rear->link;
    if(Rear->link && Rear->link->expon == e){
       if(Rear->link->coef + c)//判别一下加完是否为0,若不为0则直接加进去,若为0就删掉把内存空间释放
           Rear->link->coef += c;
        else{
            t = Rear -> link;
            Rear->link = t ->link;
            free(t);
        }
    }else{//不相等就是小于的情况,就需要申请一个结点,然后把c跟e赋给这个结点
        t = (Polynomial)malloc(sizeof(struct PolyNode));
        t -> coef = c;t->expon = e;
        t ->link = Rear->link;
        Rear->link=t;Rear = Rear->link;
    }
        t2 = t2->link
    }
    t1 = t1 -> link
}
........

image-20220629214627763

第三处省略

t2 = P; P = P->link;free(t2);
return P;