线性表的应用1

应用1 一元多项式

a0+a1 * x1+a2 * x2+……这样的式子就是一元多项式了,只有一个变量且为指数项相加的形式。

理论上用一个结构体数组就行了,但是呢,如果是a0 + a100 * x100这样的,要是一个数组,血亏。

所以呢,链表就出来拯救世界了,此时结构体的数值域就应该是两个变量了,exp(指数)和coef(系数)

操作有加减乘除。(输入可以是无序的,在创建里面顺便排序,并处理指数相同的)

那个啥,写程序的时候默认了输入的系数都是正的。。。要是需要负值输入,就要将减法里面判断系数为零的部分加到加法里面。

1.加减
加减就是将两个有序的链表的每一项进行比较,取一个作为返回的,另一个销毁。
比较的结果,无非是 大于、小于、等于,分开讨论即可。
减法就是将加法里面的加改成了减。
另外,如果要销毁的链表在返回的链表结束了之后还没完,加法直接接上去就行,减法要有一个取反的操作,
以及在有空表的情况,加减法有所出入,剩下的基本上相似。

(减法还看到了一个思路,就是直接将减数链表里面系数取反做加法)

2.乘法
简单粗暴一点,我是直接创建新链表,然后每一项都乘一下,不管指数大小都放在新表中, 时间复杂度 o(m*n)
然后再插入到需要返回的链表的合适位置,并合并指数一样的。
(个人感觉在乘的同时解决指数的问题很困难,这样相对明了一点。)

3.除法
emm这个先咕了,因为上网找也没找到思路,有一些没有,有一些看着很诡异(可能是自己没领会到人家的深意)
然后贴代码:

#include <iostream>
//线性链表的应用,存储一元多项式并且加减乘除操作
using namespace std;

struct link
{
    int coef;//系数
    int exp;//指数
    struct link* next;
};

struct link* New_link()
{
    cout<< "Do you want a new code?"<<endl;
    struct link* head=(struct link* )malloc(sizeof(struct link));
    head->next=NULL;
    struct link* pr=head;
    char judge;
    cin>>judge;
    while(judge=='y')
    {
        int exp,coef;
        cout << "Input the coef and the exp"<<endl;//输入
        cin>>coef;
        cin>>exp;
        pr=head;
        while(pr->next)//看看有没有重复指数的
        {
            if(pr->next->exp==exp)
            {
                pr->next->coef+=coef;
                coef=0;
                break;
            }
            else
                pr=pr->next;
        }
        if(!coef)//系数为0或者是已经处理的了
        {
            cout<< "Do you want more?"<<endl;
            cin>>judge;
            continue;
        }
        struct link* p=(struct link* )malloc(sizeof(struct link));
        p->coef=coef;
        p->exp=exp;
        pr=head;
        while(pr->next)//寻找适合的插入位置,指针在链表当前的前一个位置方便插入
        {
            if(p->exp > pr->next->exp)
            {
                pr = pr->next;
            }
            else//找到了
                break;
        }
        p->next=pr->next;
        pr->next=p;
        cout<< "Do you want more?"<<endl;
        cin>>judge;
    }
    return head;
}

void deleted(struct link* head)//销毁链表
{
    struct link* p=head,*pr=NULL;
    while(p)
    {
        pr=p;
        p=p->next;
        free(pr);
    }
    free(head);
}

struct link* add(struct link* heada,struct link* headb)//相加的结果在a表里
{
    if(!heada->next)//a空
    {
        heada->next=headb->next;
        free(headb);
        return heada;
    }
    
    if(!headb->next)//b空
    {
        free(headb);
        return heada;
    }
    
    struct link* pa=heada,*pb=headb->next;//老规矩,被插入的要往前一位,便于插入
    while(pa->next&&pb)
    {
        if(pa->next->exp < pb->exp)//a往后走
            pa=pa->next;
        
        else if(pa->next->exp==pb->exp)//相同,合并
        {
            struct link* temp=pb;
            pb=pb->next;
            pa->next->coef += temp->coef;
            free(temp);
        }
        
        else//b小,要插入
        {
            struct link* temp=pb;
            pb=pb->next;
            temp->next=pa->next;
            pa->next=temp;
            pa=pa->next;
        }
    }
    
    if(pb)//b表没完,直接接上
    {
        pa->next=pb;
    }
    
    free(headb);
    return heada;
}

struct link* subtraction(struct link* heada,struct link* headb)//相减同样结果在a里面
{
    if(!headb->next)//b空
    {
        free(headb);
        return heada;
    }
    
    else if(!heada->next)//a空,这时b里面的每一项要取反
    {
        heada->next=headb->next;
        free(headb);
        struct link* p=heada->next;
        while(p)
        {
            p->coef = -p->coef;
            p = p->next;
        }
        return heada;
    }
    
    struct link* pa=heada,*pb=headb->next;
    while(pa->next&&pb)
    {
        if(pa->next->exp < pb->exp)
            pa=pa->next;
        
        else if(pa->next->exp == pb->exp)
        {
            struct link* temp=pb;
            pb=pb->next;
            pa->next->coef-=temp->coef;
            free(temp);
            if(!pa->next->coef)//如果刚好抵消
            {
                temp=pa->next;
                pa->next = temp->next;
                free(temp);
            }
        }
        
        else
        {
            struct link* temp=pb;
            pb=pb->next;
            temp->coef=-temp->coef;
            temp->next=pa->next;
            pa->next=temp;
        }
    }
    
    while(pb)
    {
        pb->coef= -pb->coef;
        pa->next=pb;
        pb=pb->next;
    }
    
    free(headb);
    return heada;
}

struct link* multiplication(struct link* heada,struct link* headb)//乘法
{
    struct link* pa=heada->next, *pb=headb->next;
    struct link* headc=(struct link* )malloc(sizeof(struct link));//直接塞到这个链表里面,然后再放到a中同时处理
    headc->next=NULL;
    struct link* pc=headc;

    if(!(pa&&pb))//有一个为空
        return NULL;

    while(pb)//双重循环保证每一个都有被乘
    {
        pa=heada->next;
        while(pa)
        {
            struct link* p = (struct link* )malloc(sizeof(struct link));//尾插c表
            p->coef = pa->coef * pb->coef;
            p->exp = pa->exp + pb->exp;
            p->next = pc->next;
            pc->next = p;
            pc = pc->next;//保证pc在最后
            pa = pa->next;
        }
        pb=pb->next;
    }

    deleted(headb);
    deleted(heada->next);//删除头节点之外的点
    heada->next=NULL;//这个别忘了

    struct link* temp=headc->next;//先将第一个插入,不然循环跑不起来
    pc=temp->next;
    headc->next=pc;
    temp->next=heada->next;
    heada->next=temp;

    while(pc)//将headc里面的整合到heada里面
    {
        struct link* p=heada;
        while(p->next)
        {
            if(p->next->exp == pc->exp)
            {
                p->next->coef += pc->coef;
                pc=pc->next;
                break;
            }
            
            else if(p->next->exp > pc->exp)//插入
            {
                temp=pc;
                pc=pc->next;
                temp->next=p->next;
                p->next=temp;
                break;
            }
            
            else
                p=p->next;
        }
        
        if(!p->next)//没有合适的位置,尾插
        {
            temp = pc;
            pc=pc->next;
            temp->next=p->next;
            p->next = temp;
        }
    }
    
    deleted(headc);
    return heada;
}

int main()
{
    struct link* heada=New_link(),*headb=New_link();
    struct link* p=NULL;
    
    cout<< "What do you want?"<<endl;
    char judge;
    cin>>judge;
    
    switch(judge)
    {
        case '+':
        {
            heada=add(heada,headb);//加
            cout<< "Now I will show you add:"<<endl;
            p=heada->next;
            while(p)
            {
                cout << p->coef<< " x^"<<p->exp<<endl;
                p=p->next;
            }
            break;
        }
        
        case '-':
        {
            heada=subtraction(heada,headb);//减
            cout<< "Now I will show you subtraction:"<<endl;
            p=heada->next;
            while(p)
            {
                cout << p->coef<< " x^"<<p->exp<<endl;
                p=p->next;
            }
            break;
        }
        
        case '*' :
        {
            heada=multiplication(heada,headb);
            cout<< "Now I  will show you multiplication:"<<endl;
            p=heada->next;
            while(p)
            {
                cout << p->coef<< " x^"<<p->exp<<endl;
                p=p->next;
            }
            break;
        }
        
        case '/' :
        {
            //heada=division(heada,headb);
            cout<< "Now I  will show you multiplication:"<<endl;
            p=heada->next;
            while(p)
            {
                cout << p->coef<< " x^"<<p->exp<<endl;
                p=p->next;
            }
            break;
        }
        
        default :
            cout<< "Wrong input!"<<endl;
    }
    deleted(heada);
    return 0;
}

emm我这个创建有一点憨批,下面给一个例子:
y
0 1
y
10 5
y
1 7
y
2 5
y
1 6
n
y
3 4
y
10 5
y
1 6
y
2 3
y
1 8
n
输入上面的然后就到了switch那步,加减乘除自己选。
上面的例子为
a: 0 x1+10 x5+1 x7+2 x5+1 x6
b: 3 x4+10 x5+1 x6+2 x3+1 x8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值