多项式(Polynomial)的运算——利用单链表

多项式(Polynomial)的运算——利用单链表

1. 多项式的概念

1.1 多项式的定义
  • 有限的单项式之和称为多项式,其中每个单项式叫做多项式的项,不含字母的项叫做常数项。
  • 多项式里,次数最高的项的次数叫做这个多项式的次数。
  • 多项式按某个字母降或升幂排序。
  • 单项式与多项式统称为整式。
1.2 多项式的表示
  • 通常在数学中对一元n次多项式可表示成如下的形式,设多项式的最高可能阶数为maxDegree,当前的最高阶数为n,各个项按指数递增的次序,从0到n顺序排列。
    (1)一元n次多项式的数学式:
    Pn(x)=a0+a1x+a2x2+a3x3++an1xn1+anxn=ni=0aixi
    (2)一元n次多项式的存储表示:

    编号0123……nmaxDegree
    coef a0 a1 a2 a3 …… an ……
  • 缺很多项而且各项指数跳动很大的一元多项式称为稀疏多项式。如果在存储多项式时只存储那些系数非零的项,可以节省存储空间。因此,对于每一个系数非零的项只存储它的系数 ai 和指数 ei ,并用一个存储各系数非零项的数组来表示这个多项式。其中,每个 ai Pn(x) 中的非零系数,指数 ei 是递增的,即0≤ e0 < e1 <……< em
    (1)一元多项式的数学式:
    Pn(x)=a0xe0+a1xe1+a2xe2+a3xe3++amxem
    (2)一元多项式的存储表示:

    编号0123……i……mmaxDegree
    coef a0 a1 a2 a3 …… ai …… am ……
    exp e0 e1 e2 e3 …… ei …… em ……
1.3 多项式的运算法则
  • 多项式的加法:指多项式中同类项的系数相加,字母保持不变(即合并同类项)。
  • 多项式的乘法:指把一个多项式中的每个单项式与另一个多项式中的每个单项式相乘之后合并同类项。

2. 多项式运算的实现

2.1 多项式的结点结构定义
  • (1)文件:Term.h

    
    #ifndef TERM_H_
    
    
    #define TERM_H_
    
    
    
    #include <iostream>
    
    
    #include <string>
    
    
    #include <strstream>
    
    
    using namespace std;
    
    struct Term             //多项式结点的定义
    {
        float coef;         //数据域——系数
        int exp;            //数据域——指数
        Term *link;         //指针域——后继指针
        //初始化数据与指针成员的构造函数
        Term(float c, int e, Term* ptr = NULL){ coef = c; exp = e; link = ptr; }
    };
    
    
    #endif /* TERM_H_ */
    
2.2 多项式的类定义及其操作的实现
  • 文件:Polynomial.h

    
    #ifndef POLYNOMIAL_H_
    
    
    #define POLYNOMIAL_H_
    
    
    
    #include "Term.h"
    
    
    class Polynomial//带附加头结点
    {
    public:
        Polynomial();                                                   //构造函数
        Polynomial(const Polynomial& L);                                //拷贝构造函数
        ~Polynomial();                                                 //析构函数
    public:
        Term* Search(const int e)const;                                 //搜索数据值为x的结点并返回
        Term* InsertAfter(Term* lastNode, const float c, const int e);  //后插法建立链表
        void Output()const;                                             //输出所有结点的数据值
        void Sort();                                                    //表排序——冒泡排序
        void MakeEmpty();                                               //清空链表(保留附加头结点)
    public:
        Term* GetHead()const;                                           //返回附加头结点的地址
        int GetMaxOrder();                                              //获取最大阶数    
    private:
        Term *first;                                                    //链表的头结点
    };
    
    //构造函数
    Polynomial::Polynomial()
    : first(new Term(0, -1))
    {
        cout << "$ 执行构造函数" << endl;
    }
    
    //拷贝构造函数
    Polynomial::Polynomial(const Polynomial& L)
    {
        cout << "$ 执行拷贝构造函数" << endl;
        Term *srcptr = L.GetHead();
        Term *destptr = first = new Term(0, -1);
        while (NULL != srcptr->link)
        {
            srcptr = srcptr->link;
            destptr->link = new Term(srcptr->coef, srcptr->exp);
            destptr = destptr->link;
        }
    }
    
    //析构函数
    Polynomial::~Polynomial()
    {
        cout << "$ 执行析构函数" << endl;
        MakeEmpty();
    }
    
    //搜索数据值为x的结点并返回
    Term* Polynomial::Search(const int e)const
    {
        Term *curNode = first->link;
        while ((NULL != curNode) && (e != curNode->exp))
        {
            curNode = curNode->link;
        }
        return curNode;
    }
    
    //后插法建立链表
    Term* Polynomial::InsertAfter(Term* lastNode, const float c, const int e)
    {
        if ((c == 0) || (e < 0))
        {
            return lastNode;
        }
        Term *curNode = Search(e);
        if (NULL != curNode)
        {
            curNode->coef += c;
            return lastNode;
        }
        Term *newNode = new Term(c, e);
        lastNode->link = newNode;
        return lastNode->link;
    }
    
    //输出所有结点的数据值
    void Polynomial::Output()const
    {
        Term *curNode = first->link;
        if (NULL != curNode)
        {
            cout << "Pn(x) = ";
        }
        while (NULL != curNode)
        {
            if ((first->link != curNode) && (curNode->coef > 0))
            {
                cout << "+";
            }
            if (0 == curNode->exp)
            {
                cout << curNode->coef;
            }
            else
            {
                cout << curNode->coef << "*x^" << curNode->exp; 
            }
            curNode = curNode->link;
    
        }
        cout<<endl;
    }
    
    //表排序——冒泡排序
    void Polynomial::Sort()
    {
        Term *curNode = first->link;
        while (NULL != curNode)
        {
            Term *nextNode = curNode->link;
            while (NULL != nextNode)
            {
                if (curNode->exp < nextNode->exp)
                {
                    float coef_temp = curNode->coef;
                    curNode->coef = nextNode->coef;
                    nextNode->coef = coef_temp;
                    int exp_temp = curNode->exp;
                    curNode->exp = nextNode->exp;
                    nextNode->exp = exp_temp;
                }
                nextNode = nextNode->link;
            }
            curNode = curNode->link;
        }
    }
    
    //清空链表(保留附加头结点)
    void Polynomial::MakeEmpty()
    {
        Term *curNode = NULL;
        while (NULL != first->link)         //当链表不为空时,删去链表中所有结点
        {
            curNode = first->link;          //保存被删结点
            first->link = curNode->link;    //将链表附加头结点中指针域的指针指向被删结点的下一个结点
            delete curNode;                 //从链表上摘下被删结点
        }
    }
    
    //返回附加头结点的地址
    Term* Polynomial::GetHead()const
    {
        return first;
    }
    
    //获取最大阶数
    int Polynomial::GetMaxOrder()
    {
        Sort();
        if (NULL == first->link)
        {
            return -1;
        }
        return first->link->exp;
    }
    
    
    #endif /* POLYNOMIAL_H_ */
    
2.3 多项式加法运算的实现
  • 文件:PolynomialAdd.h

    
    #ifndef POLYNOMIAL_ADD_H_
    
    
    #define POLYNOMIAL_ADD_H_
    
    
    
    #include "Polynomial.h"
    
    
    Polynomial operator + (Polynomial& polynomial1, Polynomial& polynomial2)
    { 
        Polynomial destpolynomial;
        Term *destlastNode = destpolynomial.GetHead();
        Term *curNode1 = polynomial1.GetHead()->link;
        Term *curNode2 = polynomial2.GetHead()->link;
        while ((NULL != curNode1) && (NULL != curNode2))
        {
            if (curNode1->exp == curNode2->exp)
            {
                if (0 != curNode1->coef + curNode2->coef)
                {
                    destlastNode = destpolynomial.InsertAfter(destlastNode, curNode1->coef + curNode2->coef, curNode1->exp);
                }
                curNode1 = curNode1->link;
                curNode2 = curNode2->link;
            }
            else if (curNode1->exp > curNode2->exp)
            {
                destlastNode = destpolynomial.InsertAfter(destlastNode, curNode1->coef, curNode1->exp);
                curNode1 = curNode1->link;
            }
            else if (curNode1->exp < curNode2->exp)
            {
                destlastNode = destpolynomial.InsertAfter(destlastNode, curNode2->coef, curNode2->exp);
                curNode2 = curNode2->link;
            }
        }
        return destpolynomial;
    }
    
    
    #endif /* POLYNOMIAL_ADD_H_ */
    
2.4 多项式乘法运算的实现
  • 文件:PolynomialMultiply.h

    
    #ifndef POLYNOMIAL_MULTIPLY_H_
    
    
    #define POLYNOMIAL_MULTIPLY_H_
    
    
    
    #include "Polynomial.h"
    
    
    Polynomial operator * (Polynomial& polynomial1, Polynomial& polynomial2)
    {
        Polynomial destpolynomial;
        Term *destlastNode = destpolynomial.GetHead();
        Term *curNode1 = polynomial1.GetHead()->link;
        while (NULL != curNode1)
        {
            Term *curNode2 = polynomial2.GetHead()->link;
            while (NULL != curNode2)
            {
                destlastNode = destpolynomial.InsertAfter(destlastNode, curNode1->coef * curNode2->coef, curNode1->exp + curNode2->exp);
                curNode2 = curNode2->link;
            }
            curNode1 = curNode1->link;
        }
        return destpolynomial;
    }
    
    
    #endif /* POLYNOMIAL_MULTIPLY_H_ */
    
2.5 主函数(main函数)的实现
  • 文件:main.cpp

    
    #include "PolynomialAdd.h"  
    
    
    #include "PolynomialMultiply.h"
    
    
    //返回输入的结点数据值
    template <class T>
    T get_value(const string& content)
    {
        string value;
        cout << content;
        cin >> value;
        return StrToTtype<T>(value);
    }
    
    //类型转换——将string型转为模板类型T
    template <class T>
    T StrToTtype(const string& s_num)
    {
        T n_num;
        strstream ss_num;
        ss_num << s_num;
        ss_num >> n_num;
        return n_num;
    }
    
    //构造多项式
    void construct_polynomial(Polynomial* linkedList)
    {
        Term *lastNode = linkedList->GetHead();
        float coef = get_value<float>("newNode->coef = ");
        int exp = get_value<int>("newNode->exp = ");
        while ((coef != 0) && (exp >= 0))
        {
            lastNode = linkedList->InsertAfter(lastNode, coef, exp);
            coef = get_value<float>("newNode->coef = ");
            exp = get_value<int>("newNode->exp = ");
        }
        linkedList->Sort();
        linkedList->Output();
    }
    
    int main(int argc, char* argv[])
    {
        Polynomial *polynomial1 = new Polynomial;
        construct_polynomial(polynomial1);
    
        Polynomial *polynomial2 = new Polynomial;
        construct_polynomial(polynomial2);
    
        Polynomial adddest = (*polynomial1) + (*polynomial2);
        adddest.Output();
    
        Polynomial multiplydest = (*polynomial1) * (*polynomial2);
        multiplydest.Output();
    
        delete polynomial1;
        delete polynomial2;
    
        system("pause");
        return 0;
    }

参考文献:
[1]《数据结构(用面向对象方法与C++语言描述)(第2版)》殷人昆——第二章
[2]《C/C++常用算法手册》秦姣华、向旭宇——第六章
[3] 百度搜索关键字:多项式、多项式的运算

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值