05、线性表案例2:一元多项式相加

题源及算法思路来源于“网易云课堂:数据结构实战完全手册(夏曹俊·丁宋涛)”

一元多项式相加的需求

  用链表的形式表示一元多项式,并完成一元多项式的相加操作,形成新的一元多项式。

一元多项式相加的实现

#include "stdio.h"
#include "stdlib.h"

// 设计数据项的数据结构
typedef struct PolynomialNode
{
    int n_Coefficient;// 系数
    int n_Exponent;// 指数
    PolynomialNode* pNext;// 指针域
}PolynomialNode;

// 为多项式链表新增结点,并返回新结点的地址
PolynomialNode* AttachNode(int coef, int expo, PolynomialNode* precursor)
{
    // coef:新结点的系数、expo:新结点的指数、precursor:新结点的直接前驱结点
    PolynomialNode* pTemp;
    pTemp = (PolynomialNode*)malloc(sizeof(PolynomialNode));// 动态分配新结点内存
    
    // 为新结点数据项和指针域赋值
    pTemp->n_Coefficient = coef;
    pTemp->n_Exponent = expo;
    precursor->pNext = pTemp;

    return pTemp;
}

/* 将PolyA和PolyB进行相加,将结果放入PolyC中
   所有的存储结构按照幂指数升序从前往后排列
   输入:PolyA和PolyB的首地址
   输出:PolyC的首地址
*/
PolynomialNode* MergePolynomial(PolynomialNode* pHeadA, PolynomialNode* pHeadB)
{
    PolynomialNode* pHeadC;// 需要返回的多项式C的地址
    PolynomialNode* pTempA;// 用来操作多项式A的临时结点
    PolynomialNode* pTempB;// 用来操作多项式B的临时结点
    PolynomialNode* pTempC;// 用来操作多项式C的临时结点
    PolynomialNode* pTemp;// 用来帮助执行多项式A和B组合的结点

    int n_TempCoef = 0;// 新结点的系数

    pHeadC = (PolynomialNode*)malloc(sizeof(PolynomialNode));// 动态分配PolyC的头结点

    pTempA = pHeadA->pNext;
    pTempB = pHeadB->pNext;
    pTempC = pHeadC;

    // 遍历PolyA和PolyB执行Merge操作直到其中一个表遍历完结
    while(pTempA && pTempB)
    {
        if(pTempA->n_Exponent == pTempB->n_Exponent)// 如果PolyA和PolyB两个多项式的当前结点指数相等,则将其合并
        {
            n_TempCoef = pTempA->n_Coefficient + pTempB->n_Coefficient;// 计算新结点的系数
            if(n_TempCoef != 0)// 判断新结点的系数是否为零,不为零才可以生成新结点
            {
                pTempC = AttachNode(n_TempCoef, pTempA->n_Exponent, pTempC);
            }
            // PolyA和PolyB的当前结点后移
            pTempA = pTempA->pNext;
            pTempB = pTempB->pNext;
            
            continue;
        }
        // 如果两个多项式的当前结点指数不相等,则把指数相对小的结点接到PolyC表中,并让这个相对小的结点做后移操作
        if(pTempA->n_Exponent < pTempB->n_Exponent)
        {
            pTemp = pTempA;
            pTempA = pTempA->pNext;
        }
        if(pTempA->n_Exponent > pTempB->n_Exponent)
        {
            pTemp = pTempB;
            pTempB = pTempB->pNext;
        }
        pTempC = AttachNode(pTemp->n_Coefficient, pTemp->n_Exponent, pTempC);
    }

    // 检查PolyAhePolyB是否均遍历完
    pTemp = pTempA;
    if(pTempA == NULL)
    {
        pTemp = pTempB;
    }

    // 将未遍历完的表的剩下的结点依次插入PolyC中
    while(pTemp)
    {
        pTempC = AttachNode(pTemp->n_Coefficient, pTemp->n_Exponent, pTempC);
        pTemp = pTemp->pNext;
    }
    pTempC->pNext = NULL;// PolyC表尾置空
    
    return pHeadC;
}

// 遍历多项式结点
void TraversalPolyList(PolynomialNode* pHead)
{
    PolynomialNode* pTemp;//用来操作多项式pHead的临时结点
    pTemp = pHead->pNext;

    int n_Count = 0;

    // 遍历多项式链表并输出
    while(pTemp != NULL)
    {
        n_Count++;//计数器自增

        // 如果当前结点的指数为0
        if(pTemp->n_Exponent == 0)
        {
            printf("%d", pTemp->n_Coefficient);
            pTemp = pTemp->pNext;
            continue;
        }

        // 如果当前结点的指数为1
        if(pTemp->n_Exponent == 1)
        {
            // 如果是输出第一个结点
            if(n_Count == 1)
            {
                printf("%dx", pTemp->n_Coefficient);
                pTemp = pTemp->pNext;
                continue;
            }
            
            // 如果不是输出第一个结点,则区分当前结点的系数正负两种不同输出方式
            if(pTemp->n_Coefficient > 0)
            {
                printf(" + %dx", pTemp->n_Coefficient);
            }
            else
            {
                printf(" + (%dx)", pTemp->n_Coefficient);
            }
            pTemp = pTemp->pNext;
            continue;
        }

        // 如果当前结点的指数不是0也不是1,那么在区分是否是输出第一个结点的基础上,也区分系数的正负
        if(n_Count == 1)
        {
            printf("%dx^%d", pTemp->n_Coefficient, pTemp->n_Exponent);
        }
        else
        {
            if(pTemp->n_Coefficient > 0)
            {
                printf(" + %dx^%d", pTemp->n_Coefficient, pTemp->n_Exponent);
            }
            else
            {
                printf(" + (%dx^%d)", pTemp->n_Coefficient, pTemp->n_Exponent);
            }
        }

        pTemp = pTemp->pNext;
    }
    printf("\n");
}

/* PolyA = 1 + 2x + 3x^2
   PolyB = 3x + 4x^2 + 5x^3 + 6x^4
*/
int main()
{
    PolynomialNode* pHeadA = (PolynomialNode*)malloc(sizeof(PolynomialNode));
    PolynomialNode* pHeadB = (PolynomialNode*)malloc(sizeof(PolynomialNode));

    PolynomialNode* pTempA = pHeadA;
    PolynomialNode* pTempB = pHeadB;

    for(int i = 0; i < 3; i++)
    {
        pTempA = AttachNode(i + 1, i, pTempA);
    }
    pTempA->pNext = NULL;
    TraversalPolyList(pHeadA);

    for(int i = 0; i < 4; i++)
    {
        pTempB = AttachNode(i + 3, i + 1, pTempB);
        
    }
    pTempB->pNext = NULL;
    TraversalPolyList(pHeadB);

    PolynomialNode* pHeadC = (PolynomialNode*)malloc(sizeof(PolynomialNode));
    pHeadC = MergePolynomial(pHeadA, pHeadB);
    TraversalPolyList(pHeadC);

    system("pause");

    return 0;
}

你可能感兴趣的:(数据结构,学习笔记)