数据结构 线性表的基本操作

【实验目的】

1、掌握线性表的定义及其基本操作,如建立、查找、插入和删除等;

2、掌握线性表的两类不同的存储结构的描述方法,掌握单链表的建立、查找、插入和删除等算法。

【实验内容】

设计一个一元多项式简单计算器。

【实验要求】

以带表头结点的单链表形式存储多项式,多项式的项数存放在头结点中。

1、输入并建立多项式f和g;

2、建立多项式h=f+g;

3、输出多项式h,输出形式为整型序列,其中n为多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列;

4、系统完成后,提交实验报告。

【实验步骤】

1、单链表的类型定义

2、各模块的功能

(1)多项式的创建

【算法步骤】

1)创建一个只有头结点的空链表;

2)根据多项式的项的个数n,循环n次执行以下操作:

\bullet生成一个新节点*s;

\bullet输入多项式当前项的系数和指数赋给新节点*s的数据域;

\bullet设置一个前驱节点pre,用于指向待找到的一个大于输入项的指数的节点的前驱,pre初始时指向头节点;

\bullet指针q初始化,指向首元结点;

\bullet循环向下逐个比较链表中当前节点中的值与输入项指数,找到第一个直达与输入项指数的节点*q;

\bullet将输入项节点*s插入*q和其前驱节点pre之间。

【算法描述】

/* 多项式的创建*/
void CreatePolyn(Polynomial& p, int n) //输入n项的系数和指数,建立表示多项式的有序列表P
{
    p = new PNode;
    Polynomial s , pre , q; 
    p->next = NULL;            //先建立一个带头节点的单链表
    int i;
    for (i = 1; i <= n; ++i)          //依次输入n个非零项
    {
        printf("请输入第%d系数和指数:\n", i);
        s = new PNode;                    //生成新节点
        scanf_s("%f,%d",&s->coef,&s->expn);     //输入系数和指数
        pre = p;                             //pre用于保存q的前驱,初值为头节点
        q = p->next;                        //q初始化,指向首元结点
        while (q && q->expn < s->expn)      //通过比较指数找到第一个大于输入项指数的项*q
        {
            pre = q;
            q = q->next;
        }
        s->next = q;                       //将输入项s插入*q和其前驱节点pre之间
        pre->next = s;
    }

(2)打印多项式

【算法步骤】

用while判断系数是否大于零、小于零、等于零。

【算法描述】

/*打印多项式.*/
void PrintPolyn(Polynomial &pre)	
{
    int w = 1;
    Polynomial p= pre->next;
    if (!p) {
        putchar('0');
        printf("\n");
        return;
    }
    while (p) 
    {
        if (p->coef > 0 && w != 1)    /*多项式中某一项系数大于0,输出+号*/
        {		
            putchar('+');
        }
        if (p->coef != 1 && p->coef != -1)/*多项式系数不是正负1*/
        {		
            printf("%f", p->coef);			/*%g表示以%f%e中较短的输出宽度输出单双精度实数*/
            if (p->expn == 1) putchar('X');	/*若指数为1,输出X*/
            else if (p->expn) printf("X^%d", p->expn); /*指数不为1,输出x^%d格式*/
        }
        else
        {
            if (p->coef == 1) /*系数为1*/
            {				
                if (!p->expn) putchar('1');
                else if (p->expn == 1) putchar('X');
                else printf("X^%d", p->expn);
            }
            if (p->coef == -1)/*系数为-1*/
            {			
                if (!p->expn) printf("-1");
                else if (p->expn == 1) printf("-X");
                else printf("-X^%d", p->expn);
            }
        }
        p = p->next;
        w++;
    }
    printf("\n");
}

(3)多项式的相加

【算法步骤】

 

【算法描述】

/*多项式的相加*/
void AddPolyn(Polynomial& Pa, Polynomial& Pb)
{ /*多项式加法:Pa=Pa+Pb,利用两个多项式的节点构成“和多项式”*/
    PNode* f, * g, * h, * r;
    f = Pa->next;
    g = Pb->next;/*f和g初始时分别指向Pa和Pb的首元节点*/
    h = Pa;/*h指向多项式的当前节点,初值为Pa*/
    int sum = 0;
    while (f && g) /*f和g均非空*/
    {
        if (f->expn == g->expn) /*指数相等*/
        {
            sum = f->coef + g->coef;/*sum保存两项的系数和*/
            if (sum != 0)         /*系数和不为0*/
            {
                f->coef = sum;   /*修改Pa当前指向节点的系数值为两项系数的和*/
                h->next = f;
                h = f;/*将修改后的Pa当前指向节点连接在h之后,h指向f*/
                f = f->next;/*f指向后一项*/
                r = g;
                g = g->next;
                delete r;/*删除Pb当前指向节点,g指向后一项*/
            }
            else/*系数和为零*/
            {
                r = f;
                f = f->next;
                delete r;/*删除Pa当前指向节点,f指向后一项*/
                r = g;
                g = g->next;
                delete r;/*删除Pb当前指向节点,g指向后一项*/
            }
        }
        else if (f->expn < g->expn)/*Pa当前指向节点的指数值小*/
        {
            h->next = f;/*将f链接在h之后*/
            h = f; /*h指向f*/
            f = f->next;/*f指向后一项*/
        }
        else   /*Pb当前指向当前的指数值小*/
        {
            h->next = g;/*将g链接在h之后*/
            h = g;/*h指向g*/
            g = g->next;/*g指向后一项*/
        }
    }
    h->next = f ? f : g;/*插入空多项式的剩余段*/
    delete Pb;/*释放Pb的头结点*/
    PrintPolyn(Pa);
}

 (4)主函数

【算法描述】

int main() {
    PNode* f, * g;
    int n1, n2;
    printf("请输入f的项数\n");
    scanf_s("%d", &n1);
    CreatePolyn(f, n1);
    printf("多项式f=");
    PrintPolyn(f);
    printf("请输入g的项数\n");
    scanf_s("%d", &n2);
    CreatePolyn(g, n2);
    printf("多项式g=");
    PrintPolyn(g);
    printf("多项式f和g的和为:h=");
    AddPolyn(f, g);
    return 0;
}

3、各模块之间的调用关系

4、主要算法的流程图

 四、实验总代码及运行结果

【源程序代码】

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

/*单链表类型定义*/
typedef struct PNode {
    float coef;            //系数
    int expn;              //指数
    struct PNode* next;    //指针域
}PNode, * Polynomial;      //Polynomial为指向结构体PNode的指针类型

/* 多项式的创建*/
void CreatePolyn(Polynomial& p, int n) //输入n项的系数和指数,建立表示多项式的有序列表P
{
    p = new PNode;
    Polynomial s , pre , q; 
    p->next = NULL;            //先建立一个带头节点的单链表
    int i;
    for (i = 1; i <= n; ++i)          //依次输入n个非零项
    {
        printf("请输入第%d系数和指数:\n", i);
        s = new PNode;                    //生成新节点
        scanf_s("%f,%d",&s->coef,&s->expn);     //输入系数和指数
        pre = p;                             //pre用于保存q的前驱,初值为头节点
        q = p->next;                        //q初始化,指向首元结点
        while (q && q->expn < s->expn)      //通过比较指数找到第一个大于输入项指数的项*q
        {
            pre = q;
            q = q->next;
        }
        s->next = q;                       //将输入项s插入*q和其前驱节点pre之间
        pre->next = s;
    }
}

/*打印多项式.*/
void PrintPolyn(Polynomial &pre)	
{
    int w = 1;
    Polynomial p= pre->next;
    if (!p) {
        putchar('0');
        printf("\n");
        return;
    }
    while (p) 
    {
        if (p->coef > 0 && w != 1)    /*多项式中某一项系数大于0,输出+号*/
        {		
            putchar('+');
        }
        if (p->coef != 1 && p->coef != -1)/*多项式系数不是正负1*/
        {		
            printf("%f", p->coef);			/*%g表示以%f%e中较短的输出宽度输出单双精度实数*/
            if (p->expn == 1) putchar('X');	/*若指数为1,输出X*/
            else if (p->expn) printf("X^%d", p->expn); /*指数不为1,输出x^%d格式*/
        }
        else
        {
            if (p->coef == 1) /*系数为1*/
            {				
                if (!p->expn) putchar('1');
                else if (p->expn == 1) putchar('X');
                else printf("X^%d", p->expn);
            }
            if (p->coef == -1)/*系数为-1*/
            {			
                if (!p->expn) printf("-1");
                else if (p->expn == 1) printf("-X");
                else printf("-X^%d", p->expn);
            }
        }
        p = p->next;
        w++;
    }
    printf("\n");
}

/*多项式的相加*/
void AddPolyn(Polynomial& Pa, Polynomial& Pb)
{ /*多项式加法:Pa=Pa+Pb,利用两个多项式的节点构成“和多项式”*/
    PNode* f, * g, * h, * r;
    f = Pa->next;
    g = Pb->next;/*f和g初始时分别指向Pa和Pb的首元节点*/
    h = Pa;/*h指向多项式的当前节点,初值为Pa*/
    int sum = 0;
    while (f && g) /*f和g均非空*/
    {
        if (f->expn == g->expn) /*指数相等*/
        {
            sum = f->coef + g->coef;/*sum保存两项的系数和*/
            if (sum != 0)         /*系数和不为0*/
            {
                f->coef = sum;   /*修改Pa当前指向节点的系数值为两项系数的和*/
                h->next = f;
                h = f;/*将修改后的Pa当前指向节点连接在h之后,h指向f*/
                f = f->next;/*f指向后一项*/
                r = g;
                g = g->next;
                delete r;/*删除Pb当前指向节点,g指向后一项*/
            }
            else/*系数和为零*/
            {
                r = f;
                f = f->next;
                delete r;/*删除Pa当前指向节点,f指向后一项*/
                r = g;
                g = g->next;
                delete r;/*删除Pb当前指向节点,g指向后一项*/
            }
        }
        else if (f->expn < g->expn)/*Pa当前指向节点的指数值小*/
        {
            h->next = f;/*将f链接在h之后*/
            h = f; /*h指向f*/
            f = f->next;/*f指向后一项*/
        }
        else   /*Pb当前指向当前的指数值小*/
        {
            h->next = g;/*将g链接在h之后*/
            h = g;/*h指向g*/
            g = g->next;/*g指向后一项*/
        }
    }
    h->next = f ? f : g;/*插入空多项式的剩余段*/
    delete Pb;/*释放Pb的头结点*/
    PrintPolyn(Pa);
}

int main() {
    PNode* f, * g;
    int n1, n2;
    printf("请输入f的项数\n");
    scanf_s("%d", &n1);
    CreatePolyn(f, n1);
    printf("多项式f=");
    PrintPolyn(f);
    printf("请输入g的项数\n");
    scanf_s("%d", &n2);
    CreatePolyn(g, n2);
    printf("多项式g=");
    PrintPolyn(g);
    printf("多项式f和g的和为:h=");
    AddPolyn(f, g);
    return 0;
}

【程序运行结果分析】

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值