数据结构笔记-一元多项式的表示和相加

129 阅读4分钟

一、顺序存储(数组)

typedef struct {
	int coef;//系数
	int exp;//指数
}Elemtype;

typedef struct {
	Elemtype elem[MAXSIZE];
	int length;
}SeqPoly;
SeqPoly p;

二、链式存储

1.建立结构体

    int coef;//系数
    int exp;//指数
    struct node* next;
}PNode, * Poly;

2.多项式相加函数

//A,B是带表头的单链表,头指针分别为pa,pb。qa,qb分别指向A,B多项式的当前搜索结点,q指向qa的直接前驱结点。
//相加后和多项式存放在A中
//多项式相加
void add(Poly& pa, Poly& pb) {
    Poly qa, qb, q;
    qa = pa->next;
    q = pa;//用q复制一份pa,使最后能够找到pa头结点。pb最后没用,直接将pb作为qb的前驱结点
    qb = pb->next;
    int sum;
    //当qa和qb均指向非空时
    while (qa && qb) {
        //若qa的指数比qb小,则qa留在A中,qa和a都右移一位
        if (qa->exp < qb->exp) {
            q = qa;
            qa = qa->next;
        }
        //若qa和qb指数相同,
        else if (qa->exp == qb->exp) {
            //qa和qb的系数相加,将qb右移一位,释放原来的qb
            sum = qa->coef + qb->coef;
            pb->next = qb->next;
            free(qb);

            qb = pb->next;
            //qb已经free掉了,找不到qb了,只能用pb来代替,切记不要写成qb = qb->next
 
            //若系数和为0,则去掉A中的qa,即将qa右移一位,释放原来的qa
            if (sum == 0) {
                q->next = qa->next;
                free(qa);
                qa = qa->next;
            }
            //若系数和不为0,则更新qa的系数为系数和,将q和qa都右移一位,进行下一步计算
            else {
                qa->coef = sum;
                q = qa; qa = qa->next;
            }
        }
        //若qa的指数比qb大,则将qb按指数大小顺序插入A中
        else {
            //qb指向pb的后继结点,即从B中删掉qb
            pb->next = qb->next;
            //将qb插在qa的前一位
            qb->next = qa;
            q->next = qb;
            //更新qa的前驱结点
            q = qb;
            //B中pb的下一位作为新的qb
            qb = pb->next;
        }
    }
    //当qa&&qb空,且qb指向非空时(即qa指向空),将qb接在q的后面作为最后一个qa
    //不要担心,如果B中剩余多个元素,也都一起挂在了A的末尾
    if (qb) {
        q->next = qb;
    }
    free(pb);
}

再吐槽一遍这个错误qb = pb->next,这里之前写成了qb=qb->next,qb已经free掉了,找不到qb了,只能用pb来代替,找这个bug找了半天。。。`

3.创建一个多项式,并按升幂排序,合并指数相同项

void CreateList(LinkList& L, int n)
{
    LinkList s;
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;
    printf("请输入每一项的系数和指数:");
    for (int i = 0; i < n; i++)
    {
        s = (LinkList)malloc(sizeof(LNode));             //定义变量节点 
        scanf_s("%d %d", &s->coef, &s->exp);
        s->next = L->next;                               //节点链入 
        L->next = s;
    }
    //升幂排序
    LinkList p, q;
    LinkList h = L;
    int temp1, temp2;
    for (p = h->next; p != NULL; p = p->next) {
        for (q = p->next; q != NULL; q = q->next) {
            if (p->exp > q->exp) {
                temp1 = p->coef;
                p->coef = q->coef;
                q->coef = temp1;
                temp2 = p->exp;
                p->exp = q->exp;
                q->exp = temp2;
            }
        }
    }

    //合并相同项
    p = h->next;
    while (p != NULL && p->next != NULL){
        if (p->exp == p->next->exp) {
            p->coef += p->next->coef;
            p->next = p->next->next;
        }
        p = p->next;
    }
}

这个函数还有一种写法,不规定项数,直到输入“0 0”结束

void CreateList(LinkList& L)
{
    LinkList s;
    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;
    printf("请输入每一项的系数和指数:");
    while(1)
    {
        s = (LinkList)malloc(sizeof(LNode));             //定义变量节点 
        scanf_s("%d %d", &s->coef, &s->exp);
        if (s->coef == 0 && s->exp == 0)break;
        s->next = L->next;                               //节点链入 
        L->next = s;
    }
//下同上一种写法

4.输出多项式

void Display(LinkList L)
{
        LinkList s;
        s = L->next;
        while (s)
        {
            printf(" %dX^%d", s->coef, s->exp);
            s = s->next;
            if (s != NULL)
            {
                if (s->coef >= 0)
                    printf(" +");//若下一项系数为正,则打印'+',否则不打印 
                //若下一项系数为负,自带的'-',可直接打印出来使用
            }
        }
}

5.一元多项式求值

double Value(LinkList L, int x){
    float res = 0;
    while (L->next) {
        L = L->next;
        res += L->coef * pow(x, L->exp);
    }
    return res;
}

6.删除一元多项式中指定指数的项

void DeleteElem(LinkList& L, int e){
    LinkList p, q;
    if (L->next == NULL)return;
    p = L->next;
    q = L;
    while (p != NULL) {
        if (p->exp == e) {
            q->next = p->next;//要删除的是p
            free(p);
            p = q->next;
        }
        else
        {
            q = p;
            p = p->next;
            //p和q都右移一位
        }
    }
}

7.主函数

{
    LinkList ha, hb;
    int x, n;
    double val;
    printf("请输入x的值:");
    scanf_s("%d", &x); //读入x
    printf("\n请输入多项式的项数:");
    scanf_s("%d", &n);

    CreateList(ha,n);//创建单链表ha存放一元多项式
    printf("ha = ");
    Display(ha);   //遍历单链表输出一元多项式
    val = Value(ha, x);
    printf(" = %f\n", val);

    CreateList(hb,n);//创建单链表hb存放一元多项式
    printf("hb = ");
    Display(hb);   //遍历单链表输出一元多项式
    val = Value(hb, x);
    printf(" = %f\n", val);

    AddPoly(ha, hb);//ha = ha + hb 
    printf("ha+hb = ");
    Display(ha);
    val = Value(ha, x);
    printf(" = %f\n", val);

    printf("请输入需要删除的多项式指数项:");
    scanf_s("%d", &x); //读入待删除的多项式指数项
    DeleteElem(ha, x);
    printf("ha = ");
    Display(ha);

    return 0;
}