数据结构-链表实现多项式求和

浙江大学数据结构课程第二讲练习:使用链表实现多项式求和与乘积,只写了求和,乘积暂时没写。

#include <iostream>
#include <stdio.h>
using namespace std;

//Polynomial是typedef为PolyNode *类型声明的别名
typedef struct PolyNode *Polynomial;
struct PolyNode
{
    int coef;
    int expon;
    Polynomial link;
};

void Attach(int c, int e, Polynomial *pRear) /* *pRear是指向指针的指针,这里是为了按值传递从而改变Rear的值 */
{
    Polynomial P;

    P = (Polynomial)malloc(sizeof(struct PolyNode)); /*创建新节点,用于存储当前多项式*/
    P->link = NULL; /*因为插入每次的节点都是链表尾,所以要使其指针指向NULL*/
    P->coef = c; /*为新节点赋值*/
    P->expon = e;
    (*pRear)->link = P;
    *pRear = P; /*----------------改变Rear指向当前链表结尾-----------------*/
}

Polynomial ReadPoly()
{
    Polynomial P,t;
    Polynomial    Rear; /*当前结果表达式尾项指针*/
    int c, e, N;

    scanf("%d", &N); /*读入多项式总共有几项*/
    P = (Polynomial)malloc(sizeof(struct PolyNode)); P->link = NULL; /*采用申请空节点作为链表头*/
    Rear = P; /*将当前节点的指针赋予Rear*/
    if (N < 1) /*检查数据是否输入正确*/
        cout << "input is error" << endl;
    while (N--) {
        scanf("%d %d", &c, &e); /*读入多项式的系数和指数*/
        Attach(c, e, &Rear); /*将当前项插入多项式*/
    }
    t = P; P = P->link; free(t); /*释放一开始申请的空节点*/
    /*.................*/
    return P;
}

Polynomial Add(Polynomial P1, Polynomial P2)
{
    Polynomial t1, t2, P;
    Polynomial Rear;

    t1 = P1; t2 = P2; /*P1和P2指向表头,不能改变它的值,否则找不到链表*/
    P = (Polynomial)malloc(sizeof(struct PolyNode)); P->link = NULL; /*采用申请空节点作为链表头*/
    Rear = P;
    while (t1&&t2) {
        if (t1->expon == t2->expon) {
            if ((t1->coef + t2->coef) != 0){
                Attach(t1->coef + t2->coef, t1->expon, &Rear);
                t1 = t1->link;
                t2 = t2->link;
            }
            else {
                t1 = t1->link;
                t2 = t2->link;
            }
        }
        else if (t1->expon > t2->expon) {
            Attach(t1->coef, t1->expon, &Rear);
            t1 = t1->link;
        }
        else {
            Attach(t2->coef, t2->expon, &Rear);
            t2 = t2->link;
        }
    }
    while (t1) {
        Attach(t1->coef, t1->expon, &Rear); 
        t1 = t1->link;
    }
    while (t2){
        Attach(t2->coef, t2->expon, &Rear);
        t2 = t2->link;
    }
    Polynomial t;
    t = P; P = P->link; free(t);
    return P;
}

void PrintPoly(Polynomial P)
{
    int flag = 0;
    
    if (!P) { printf("0 0\n"); return; }

    while (P){
        if (!flag)
            flag = 1;
        else
            printf(" ");
        printf("%d %d", P->coef, P->expon);
        P = P->link;
    }
    printf("\n");
}

int main()
{
    Polynomial P1, P2, P;
    P1 = ReadPoly();
    P2 = ReadPoly();
    P = Add(P1, P2);
    
    //Polynomial t; /*释放表头(为啥表头的空节点会没有释放)*/
    //t = P; P = P->link; free(t);

    PrintPoly(P);
    printf("%d %d", P->coef, P->expon);
    return 0;
}

总结:

1.表头的指针不能动,否则会找不到链表的入口

2.申请空节点作为表头时,插入数据后要把该节点的内存释放(free)

3.使用malloc申请内存

  百度百科:申请一块连续指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存

  用法举例:P = (Polynomial)malloc(sizeof(struct PolyNode)); //Polynomial是struct PolyNode*的typeof别名,P就是这块节点在内存里的存储位置

4.关于链表的指针域,存放的是指针,该指针一般指向链表下一个节点的存储位置

  P1 = (Polynomial)malloc(sizeof(struct PolyNode));

  比如P是当前节点,申请了P1节点后,令P->link = P1,即实现了为链表插入新节点

猜你喜欢

转载自www.cnblogs.com/sunrise-to-set/p/10945115.html