【数据结构】储存多项式的链表(输出计算)

题目

一个多项式形如
f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 f(x)=a_{n}x^n+a_{n-1}x^{n-1}+\cdots+a_1x+a_0 f(x)=anxn+an1xn1++a1x+a0
定义数据结构Term为:

struct Term{
	double coeff;  	//系数
	int power;  	//幂次
}

要求:

  • 试编写一个程序,该程序接收用户输入的系数和幂次对后,将其保存到链表中。输入系数和幂次对时,不要求一定按幂次由高到低的顺序输入,但最后输入的系数和幂次对中的幂次必定为 0 0 0;
  • 然后,按幂次对由高到低打印出用户输入的多项式,其中每个项形如 a i x i a_ix^i aixi
  • 最后,程序反复提示用户输入 x x x的值,并计算出该多项式的值,直到输入 x x x的值为0时程序执行结束。

思路

  1. 首先建立一个Term结构体,一个节点类,一个链表类,用来存放数据。
  2. 对链表中的(Term元素)按幂的大小进行排序。
  3. 输出/计算链表中的数据。

程序

#include <iostream>
#include <math.h>
using namespace std;
struct Term
{
    double coeff;           //系数
    int power;              //幂次
};

template <class T>
class Node{					//节点类
public:	
    T data;
    Node<T> * next;
    Node<T> * pre;
    Node(const T& item){
        data=item;
        next=NULL;
        pre=NULL;
    }
    ~Node(){

    }
};

// 1->2->3->4
// 4->3->2->1
template <class T>
class LinkList{					//链表类
private:
    Node<T> * head;
    Node<T> * pre;
    int size;
public:
    LinkList();
    ~LinkList(){}
    void insert(const T& item);      //插入链表元素
    void display();                  //打印链表元素
    void SortByPower();              //排序链表元素
    Node<T> * GetHighest();          //获得最大链表元素
    void show();                     //打印方程函数
    void DelNode(Node<T> * del);     //删除节点  没用到诶,白写了
    double calc(int x);				 //计算多项式
};

template <class T>
LinkList<T>::LinkList(){
    head=NULL;
    pre=NULL;
    size=0;
}

template <class T>
void LinkList<T>::insert(const T& item){
    Node<T> * tmp= new Node<T>(item);
    if (head==NULL)
    {
        head=tmp;
        size++;
    }
    else
    {
        tmp->next=head->next;               //一开始这里忘了要有这句,因为是中间添加节点
        tmp->pre=head;
        head->next=tmp;
        head=tmp;
        size++;
    }
}

template <class T>
void LinkList<T>::display(){
    Node<T> * ptr= head;
    for (int i=0; i<size; i++)
    {
        cout<<ptr->data.power <<"->";
        ptr=ptr->pre;       //这里一开始错了,写成了head=head->pre
    }
    cout<<endl;
}

template <class T>
void LinkList<T>::DelNode(Node<T> * Del){
    if(Del->pre==NULL){                        
        //del 1 2
        if(Del->next==NULL){     //对待删除节点没有后置节点进行讨论
            head==NULL;
        }
        else{
            Del->next->pre=NULL;   //对待删除节点有没有前置节点进行讨论
            size--;
        }    
    }

    else
    {
        Del->next->pre=Del->pre;        //忽略了Del是第一个节点,没有pre的情况
        Del->pre->next=Del->next;
        size--;
        
    }
    
}


template <class T>
Node<T> * LinkList<T>::GetHighest(){
    Node<T> * high=head;              //假设最大节点是head
    Node<T> * tmp=head->pre;                         
    for (int i = 0; i < size-1; i++)   //n个节点找最大,只要比较n-1次,n次会报错
    {
        if(head->pre==NULL)
        {
            high=head;
            }   
        if (tmp->data.power > high->data.power)         
        //虽然是模板不知道具体节点的结构但是可以这样使用元素
        {
            high=tmp;        //保存最高次幂的节点
        }
        tmp=tmp->pre;         //一开始漏了这句
    }
    return  high;
}

template <class T>
void LinkList<T>::show(){
    int time=size;
    int sum=0;                                          
    cout<<"f(x)=";
    Node<T> * high=GetHighest();          //又把这个放在循环里了
    for (int i = 0; i < time; i++)
    {
        if (high->data.power!=0)
        {
            cout<<high->data.coeff<<"x^"<<high->data.power<<"+";
        }
        else
        {
            cout<<high->data.coeff<<"x^"<<high->data.power;
        }
        high=high->next;
    }
}

template <class T>
void LinkList<T>::SortByPower(){
    Node<T> * min=head;                                             //开始把这个写在循环里面了
    for (int i =0 ; i < size; i++)
    {
        Node<T> * t=min->pre;
        while (t!=NULL)
        {
            if (t->data.power<min->data.power)
            {
                swap(t->data,min->data);
            }
            t=t->pre;
            
        }
        min=min->pre;
        //1 2 3 4 head
    }
}


template <class T>
double LinkList<T>::calc(int x){
    double sum=0;
    Node<T> * max=GetHighest();
    for (int i = 0; i < size; i++)
    {
      
        sum+=max->data.coeff*(pow(x,max->data.power));
        max=max->next;                                          //又把它放到外面了
    }

    return sum;
}

int main(){
    LinkList<Term> List;
    int p;                          //幂
    double c;                   //系数
    
    while (true)
    {
        cout<<"power?"<<endl;
        cin>>p;
        cout<<"coeff?"<<endl;
        cin>>c;
        Term term;
        term.coeff=c;
        term.power=p;
        if (term.power>0)
        {
            List.insert(term);
        }
        else if(term.power==0){
            List.insert(term);
            break;
        }

    }
    
    List.display();                 //成功测试添加元素
    // List.show();                 //成功打印出函数式子
    
    List.SortByPower();
    List.display();
    List.show();
    


    int x;
    do
    {   
        cout<<endl;
        cout<<"please input x and i will calc"<<endl;
        cin>>x;
        cout<<"结果是:"<<List.calc(x)<<endl;
    } while (x!=0);
    
    

}

后记

  • 重点是对链表元素按某个属性的排序算法(虽然思想本质上和普通的排序没有区别,实际上代码还是不一样的)
  • 有很多在遍历链表的时候把节点后移一个放到循环外边了
  • 调试真是个好东西
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值