使用自定义的简单顺序表实现一元多项式的构造,计算值和加减

1、实现简单的顺序表

2、使用顺序表实现一元多项式的构造

 

 

一、实现简单的顺序表

#include "ElemType.h"
#include "stdlib.h"



#ifndef DATASTRUCTURE_SQLIST_H
#define DATASTRUCTURE_SQLIST_H

#endif //DATASTRUCTURE_SQLIST_H

/**
 * 线性表的顺序表示和实现(数组)
 */
//操作成功
#define OK 1
//操作错误
#define ERROR 0
//操作异常
#define OVERFLOW -2
//定义元素类型,int可使用基本数据类型和用户自定义数据类型替换,根据使用场景选择
typedef int Status ;
/**
 * 顺序表的存储结构
 */
//predefine(预定义) constant(常量) maxn(n的最大值)
#define MAXN 100
typedef struct {
    ElemType *elems;            //存储空间的基地址
    int length;                 //线性表当前长度
}SqList;//sequence(序列) List(列表)

/**
 * 顺序表(顺序结构的线性表)的基本操作的实现
 */

/**
 * 构造一个空的顺序表L
 * 算法描述:开辟空间,设置顺序表长度为零,返回操作结果
 * @param L 指向顺序表的指针L
 * @return  操作结果状态码
 */
Status initList(SqList *L){
    //为顺序表分配一个大小为MAXN的数组空间
    if(L==NULL) //printf a flag
        printf("this is a flag\n");
    ;
    L->elems = (ElemType *)malloc(sizeof(ElemType)*MAXN);
    //存储分配失败,返回OVERFLOW,表示操作异常状态
    if(!L->elems) return OVERFLOW;
    //设置顺序表长度为零
    L->length = 0;
    //构造顺序表成功,返回OK
    return OK;
}

/**
 * 取顺序表L中第i个元素elem
 * 算法描述:判断i是否大于等于1且小于顺序表长度,返回ElemType数组下标为i-1的元素
 * @param L 指向顺序表的指针L
 * @param i 要获取的元素在顺序表中的位置
 * @return  操作结果状态码
 */
Status getElem(SqList *L, int i, ElemType *e){
    //如果i值不合法,返回ERROR表示操作错误
    if(i < 1 || i > L->length){
        return ERROR;
    }
    //将数组的第i个元素的赋值给e指向的内存
    *e = L->elems[i-1];
    //操作成功,返回OK
    return OK;
}

/**
 * 查找元素在顺序表中的位置
 * 算法描述:查找顺序表中和元素e相同的元素出现的位置,若没有和e匹配的元素,返回0
 * @param L 指向顺序表的指针L
 * @param e 要查找的元素
 * @return  元素在顺序表中的位置
 */
int indexOf(SqList *L, ElemType e){
    for (int i = 0; i < L->length; ++i) {
        //查找成功, 下标为i的元素是顺序表的第i+1个元素,返回i+1
        if(e == L->elems[i]){
            return i+1;
        }
    }
    //查找失败,返回0
    return 0;
}

/**
 * 在顺序表L的第i个位置插入元素e,顺序表长度加1
 * 算法描述:若i小于1或者i大于顺序表L的当前长度加1,返回ERROR,
 * 若存储空间已满,返回ERROR,首先需要将顺序表位置为n~i的元素依次后移,再在顺序表位置i上插入元素e,顺序表的长度加1
 * @param L 指向顺序表的指针L
 * @param i 插入位置i
 * @param e 要插入的元素e
 * @return 返回操作结果状态码
 */
Status insertElem(SqList *L, int i, ElemType e){
    //若i小于1或者i大于线性表L的当前长度,返回ERROR
    if(i < 1 || i > L->length + 1)  return ERROR;
    //如果存储空间已满,返回ERROR
    if(L->length == MAXN) return ERROR;
    //将线性表位置为n~i的元素依次后移
    for (int j = L->length; j >= i; --j) {
        L->elems[j] = L->elems[j-1];
    }
    //在顺序表位置i上插入元素e
    L->elems[i-1] = e;
    //线顺序表的长度加1
    ++L->length;
    return OK;
}

/**
 * 删除顺序表L上位置为i的元素,顺序表长度减1
 * 算法描述:若i小于1或者i大于顺序表L的当前长度,返回ERROR,
 * 将顺序表位置为i+1~n的元素依次前移,顺序表的长度减1
 * @param L 指向顺序表的指针L
 * @param i 删除位置i
 * @return 返回操作结果状态码
 */

Status deleteElem(SqList *L, int i){
    //若i小于1或者i大于顺序表L的当前长度,返回ERROR
    if(i < 1 || i > L->length) return ERROR;
    //将线性表位置为i+1~n的元素依次前移
    for (int j = i; j < L->length; ++j) {
        L->elems[j-1] = L->elems[j];
    }
    //顺序表的长度减1
    --L->length;
    return OK;
}

Status clearList(SqList *L){
    L->length = 0;
}

 

二、使用顺序表实现一元多项式的构造

一元多项式的ADT(Abstract Data Type)

ADT UnaryPoly{
    数据对象:D = {p0, p1, ... , pn| n(-N, p(-R}
    数据关系:R = {<p0, p1, ..., pn>| p0是一元n次多项式P(之后简称P)的0次项的系数, p1是P的1次项的系数, ..., pn是P的n次项的系数}
    基本操作:
    create(&P, p0, p1, ..., pn)
    操作结构:构造一元n次多项式P
    calculate(&ans, P, x)
    初始条件:P是一元n次多项式, x是实数
    操作结构:确定P的元,计算一元n次多项式的值并返回
    add(&P, P1, P2)
    初始条件:P1, P2是一元多项式
    操作结果:返回P1, P2的和
    sub(&P, P1, P2)
    初始条件:P1, P2是一元多项式
    操作结果:返回P1, P2的差
}ADT UnaryPoly;

 

使用顺序表的基本操作实现一元多项式的基本操作

 

#include<stdio.h>
#include "SqList.h"
#include<math.h>
#include<algorithm>

using namespace std;



/**
 * 使用顺序表实现一元多项式
 */

/**
 * 实现一元多项式的基本操作
 */

/**
 * 根据长度为n的系数数组p构造一元n次多项式L, 若n < 0 , 输入不合法, 返回ERROR
 * @param L 指向一元被创建的一元多项式的指针
 * @param p 一元多项式L0到n次项的系数数组的基址
 * @param n 一元多项式L的最高次数
 * @return 操作结果状态码
 */
Status create(SqList *L, double *p, int n) {
    //若n < 0 , 输入不合法, 返回ERROR
    if (n < 0)return ERROR;
    //初始化顺序表,得到一张空表,如果初始化失败,返回OVERFLOW
    if (initList(L) != OK) {
        return OVERFLOW;
    }
    //依次插入系数数组p下标为0, 1, ..., n-1的元素到顺序表的第1, 2, ..., n个位置,如果插入失败,返回ERROR
    for (int i = 0; i <= n; ++i) {
        if (insertElem(L, i + 1, p[i]) != OK) {
            return ERROR;
        }
    }
    //构造一元多项式成功,返回OK
    return OK;
}

/**
 * 对于确定的元为x的一元多项式L, 计算其值v
 * 若L不存在(未初始化), 返回ERROR
 * @param v 一元多项式的值
 * @param L 指向一元多项式的指针
 * @param x 给定的一元多项式的未知数的值
 * @return 操作结果状态码
 */
Status calculate(double *v, SqList *L, double x) {
    //L不存在(未初始化), 返回ERROR
    if (L == NULL) return ERROR;
    //设置一元多项式的初始值为0,然后依次累加每项的值并返回
    *v = 0;
    double *p = new double ;
    for (int i = 0; i < L->length; ++i) {
        //若取值失败,返回ERROR
        if (getElem(L, i + 1, p) != OK) return ERROR;
        *v += pow(x, i) * (*p);
    }
    //计算成功返回OK
    return OK;
}

/**
 * 求和
 * 两个一元多项式L1,L2求和,返回和L
 * @param L1    指向被加一元多项式L1的指针
 * @param L2    指向加一元多项式L2的指针
 * @param L     指向一元多项式L1与L2之和的指针
 * @return      操作结果状态码
 */

Status add(SqList *L1, SqList *L2,SqList *L) {
    //L1, L2未初始化, 返回ERROR
    if (L1 == NULL || L2 == NULL) return ERROR;
    //初始化失败,返回OVERFLOW
    if(initList(L)!=OK) return OVERFLOW;
    //初始化成功,进行多项式求和
    int len = max(L1->length,L2->length);
    for (int i = 0; i < len; ++i) {
        //设置和多项式L的次数为i的项的系数为零
        double p = 0;
        double *p1 =new double ;
        //若L1包含次数为i的项,即L1的第i+1个元素,使多项式L的次数为i的系数加上L1对应次数项的系数
        if(i<L1->length){
            //获取元素失败,返回ERROR
            if(getElem(L1,i+1,p1)!=OK) return ERROR;
            p += *p1;
        }

        //若L2包含次数为i的项,即L2的第i+1个元素,使多项式L的次数为i的系数加上L2对应次数项的系数
        if(i<L2->length){
            //获取元素失败,返回ERROR
            if(getElem(L2,i+1,p1)!=OK) return ERROR;
            p += *p1;
        }

        //和多项式添加系数为p,次数为i的项作为第i+1一个元素
        if(insertElem(L,i+1,p)!=OK)return ERROR;
    }
    return OK;
}


/**
 * 求差
 * 两个一元多项式L1,L2求差,返回和L
 * @param L1    指向被减一元多项式L1的指针
 * @param L2    指向减一元多项式L2的指针
 * @param L     指向一元多项式L1与L2之差的指针
 * @return      操作结果状态码
 */

Status sub(SqList *L1, SqList *L2,SqList *L) {
    //L1, L2未初始化, 返回ERROR
    if (L1 == NULL || L2 == NULL) return ERROR;
    //初始化失败,返回OVERFLOW
    if(initList(L)!=OK) return OVERFLOW;
    //初始化成功,进行多项式求和
    int len = max(L1->length,L2->length);
    for (int i = 0; i < len; ++i) {
        //设置和多项式L的次数为i的项的系数为零
        double p = 0;
        double *p1 = new double ;
        //若L1包含次数为i的项,即L1的第i+1个元素,使多项式L的次数为i的系数加上L1对应次数项的系数
        if(i<L1->length){
            //获取元素失败,返回ERROR
            if(getElem(L1,i+1,p1)!=OK) return ERROR;
            p += *p1;
        }

        //若L2包含次数为i的项,即L2的第i+1个元素,使多项式L的次数为i的系数减去L2对应次数项的系数
        if(i<L2->length){
            //获取元素失败,返回ERROR
            if(getElem(L2,i+1,p1)!=OK) return ERROR;
            p -= *p1;
        }

        //和多项式添加系数为p,次数为i的项作为第i+1一个元素
        if(insertElem(L,i+1,p)!=OK)return ERROR;
    }
    return OK;
}

 

测试一元多项式的基本操作的功能

 

int main() {
    double p1[] = {1,2,1};
    double p2[] = {1,0,4,3};
    SqList *L1,*L2;
    L1 = new SqList ;
    L2 = new SqList ;
    if(create(L1,p1,2)!=OK)return 0;
    if(create(L2,p2,3)!=OK)return 0;
    int x = 3;
    double *v1,*v2,*v;
    v1 = new double ;
    v2 = new double ;
    v = new double ;
    if(calculate(v1,L1,x)!=OK)return 0;
    if(calculate(v2,L2,x)!=OK)return 0;
    //printf a flag
    printf("%lf\n",*v1);
    printf("%lf\n", *v2);
    SqList *L = new SqList ;
    if(add(L1,L2,L)!=OK)return 0;
    if(calculate(v,L,x)!=OK)return 0;
    printf("%lf\n", *v);
    if(clearList(L)!=OK)return 0;
    if(sub(L1,L2,L)!=OK)return 0;
    if(calculate(v,L,x)!=OK)return 0;
    printf("%lf\n", *v);
    return 0;
}

 

测试结果

 

posted @ 2020-07-21 18:27  DNoSay  阅读(650)  评论(0编辑  收藏  举报