XDU-数据结构实验题目

实验题目一

一、单链表基本运算

【问题描述】

设计并实现线性表的单链表存储和运算。

【基本要求】

实现单链表的插入、删除和遍历运算,每种操作用一个函数实现。

插入操作:将一个新元素插入表中指定序号的位置。

删除操作:将指定序号的元素从表中删除。

遍历操作:从表头按次序输入所有元素的值,若是空表,则输出信息“empty list!”。

【实现提示】

       程序运行时,首先在main函数中创建空的、带头结点的单链表。然后多次调用实现插入操作的函数(每次都将元素在序号1位置上插入),将元素依次插入表中,最后调用实现遍历操作的函数输出所有元素。之后再多次调用实现删除操作的函数将表还原为空表(每次都删除第1个元素,每删除一个元素后,将表中剩余元素都输出一次)。

【测试数据】

       输入数据:1  2  3  4  5  0(为0时结束,0不存入链表)

第一次输出:5  4  3  2  1

第二次输出:4  3  2  1

第三次输出:3  2  1

第四次输出:2  1

第五次输出:1

第六次输出:empty list!

/*
 * Name: 数据结构上机题目1-1.cpp
 * Purpose: 单链表基本运算
 * Author: Zhang
 * Date: 2021/11/05
*/

#include <stdio.h>
#include <stdlib.h> //包含malloc函数。malloc——分配内存块,但不对内存块进行初始化;


typedef int DataType;
typedef struct node
{
    DataType data;
    struct node* link;
} LinkNode, * LinkList, * LinkList_nh;

void initList(LinkList& first)      //目的:对带头结点的单链表进行初始化并置空;算法调用方式:initList(first)
{
    first = (LinkNode*)malloc(sizeof(LinkNode));
    first->link = NULL;
}//输入:单链表表头指针:first;输出:初始化后的单链表


void printList(LinkList& first)     //目的:按顺序输出一个带头结点的单链表的所有元素的值;算法调用方式:printList(first);
{
    for (LinkNode* p = first->link; p != NULL; p = p->link)
    {
        if (p->link==NULL)          //最后一位后不加空格字符;
            printf("%d", p->data);  
        else
            printf("%d ", p->data);
    }
    printf("\n");
}//输入:单链表表头指针:first;输出:顺序输出链表各元素的值;


bool Insert(LinkList& first, int i, DataType x)      //目的:把一个新元素x插入带头结点单链表的第i个(1<=i<=n)位置;算法调用方式:bool succ = Insert(first,i,x)
{
    if (i < 0)
        return false;                                //若i不合理则返回false;
    LinkNode* p = first->link, * pr = first;         //p指向第一个结点;
    int k = 1;                                       //p指向第一个结点;
    while (p != NULL && k < i)                       //循环找第i个结点;
    {
        pr = p;
        p = p->link;
        k++;
    }                                                //pr指向p紧前结点,k为结点计数;

    LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));  //创建一个新结点;
    s->data = x;
    s->link = p;
    pr->link = s;                                       //以上三行将*s链接在*pr之后;
    return true;                                        //插入成功;
}//输入:单链表表头指针:first,元素序号:i,待插入元素值:x;输出:在指定结点插入元素值x后的单链表first;
//若插入成功,函数返回true;若插入失败,函数返回false;


bool Remove(LinkList& first, int i)                 //目的:删除带头结点单链表的第i个(1<=i<=n)结点;算法调用方式:bool succ = Remove(first,i)
{
    if (i < 0)
        return false;                               //i太小,删除失败;
    LinkNode* p = first->link, * pr = first;
    int k = 1;                                      //以上两行定位于第i个结点;
    while (p != NULL && k < i)                      //循链找第i个结点;
    {
        pr = p;
        p = p->link;
        k++;
    }                                               //pr指向p紧前结点,k为结点计数;
    if (p == NULL)
        return false;                               //i太大,删除失败;
    pr->link = p->link;                             //重新拉链,将被删结点从链中摘下;
    free(p);                                        //释放结点;
    return true;                                    //删除成功;
}//输入:单链表表头指针:first,元素序号:i;输出:删除该元素的值和删除后的单链表first;
//若删除成功,函数返回true;若删除失败,函数返回false;

int main(void)
{
    LinkNode* p;                                    //声明单链表表头指针:p
    initList(p);                                    //初始化p;

    int input = 1;                                  //假定input为1以便于接下来的判断;
    while (input != 0)                              //当输入为0时结束循环,0不存入链表;
    {
        scanf("%d", &input);                        //把输入的数据存入input;
        if (input != 0)                             //当input不为0时,存入链表;
            bool succ = Insert(p, 1, input);        //把一个符合条件的新元素input插入带头结点单链表的第1个位置(即头结点插入)
    }

    while (p->link != NULL)                         //当链表不为空时;
    {
        printList(p);                               //顺序输出链表各元素的值;
        bool succ = Remove(p, 1);                   //删除带头结点单链表的第1个结点(删除头结点);
        if (p->link == NULL)                        //删除链表完毕后,输出:empty list!
        {
            printf("empty list!\n");
            break;                                  //终止循环;
        }
    }

    return 0;                                       //主函数main返回值为0;
}

三、一元多项式相加、减运算器

本题目已完成调试!感谢梦里清扬路同学提供的帮助!!!(2021年11月24日)

【问题描述】

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

【基本要求】

一元稀疏多项式简单计算器的基本功能:

(1)输入并建立多项式的单向链表存储;

(2)输出多项式,形式为一个整数序列:,其中,n是多项式的项数,c i,e i分别是第i项的系数和指数,序列按指数降序排列;

(3)多项式A(x)和B(x)相加得到多项式C(x),输出C(x);

(4)多项式A(x)和B(x)相减得到多项式D(x),输出D(x)。

【测试数据】

【实现提示】

       用带头结点的单链表存储多项式,多项式的项数放入头结点中。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define maxSize     //项数最大个数;

typedef struct node //多项式结点的定义;
{
    double coef;    //系数;
    int exp;        //指数;
    struct node* link;
}Term, * Polynomial; //多项式的类型定义;

void initList(Polynomial& A)        //多项式初始化,并置空;
{
    A = (Term*)malloc(sizeof(Term));
    A->link = NULL;
}

void Input(Polynomial& A, double C[], int E[], int n)
{
    //从系数数组C[n]和指数数组E[n]输入一元多项式的各项,创建一个按降幂方式排列的一元多项式A。要求调用此函数前PL已存在且已置空;
    //算法调用方式:Input(Polynomial& A,double C[], int E[], int n);
    //输入:已初始化的多项式链表A,系数数组E,多项式的项数n;
    //输出:创建完成的按降幂排列的多项式链表A;

    Polynomial newTerm, p, pr;
    for (int i = 0; i < n; i++)     //输入各项的系数和指数;
    {
        p = A->link;
        pr = A;                       //按降幂查找新项插入位置;
        while (p != NULL && p->exp > E[i])
        {
            pr = p;
            p = p->link;
        }
        if (p != NULL && p->exp == E[i])    //已有指数相等的项,不插入;
            //printf("已有与指数%d相等的项,输入作废\n",E[i]);
            p->coef = p->coef + C[i];
        else
        {
            newTerm = (Term*)malloc(sizeof(Term));   //创建新结点;
            newTerm->coef = C[i];
            newTerm->exp = E[i];
            newTerm->link = p;
            pr->link = newTerm;                       //链入并保持项指数降序;
        }
    }
}

void Output(Polynomial& A)
{
    //算法调用方式:Output(A);
    //输入:多项式链表A;
    //输出:按降幂输出多项式链表A;
    
    Polynomial p = A->link;
    if (p == NULL)
        printf("0");
    bool h = 1;       //最初不输出"+"的标识;
    while (p != NULL)
    {
        if (h == 1)
        {
            if (p->coef < 0)      //第一项系数小于零输出"-";
                printf("-");
            h = 0;
        }
        else                    //非第一项输出系数符号;
        {
            if (p->coef > 0)
                printf("+");
            else
                printf("-");
        }

        if (p->exp == 0 || fabs(p->coef) != 1)
            printf("%g", fabs(p->coef));     //输出项的系数;
        
        switch (p->exp)                     //输出项的指数;
        {
        case 0:                             //常数项不输出指数;
            break;
        case 1:                             //一次项仅输出"X";
            printf("X");
            break;
        default:                            //高次项输出"X^指数";
            printf("X^%d", p->exp);
            break;
        }
        p = p->link;                          //下一项;
    }
    printf("\n");
}

void ADD(Polynomial& A, Polynomial& B, Polynomial& C)
{
    //计算C=A+B;
    //算法调用方式:ADD(A,B,C);
    //输入:有两个按降幂排列的多项式链表A和B,第三个多项式链表C也已经初始化;
    //输出:多项式A+B的结果存入升幂排列的多项式链表C;
    
    Polynomial p, q, r, s;
    double temp;
    r = C;
    p = A->link;
    q = B->link;
    
    while (p != NULL && q != NULL)              //两两比较;
    {
        if (p->exp == q->exp)               //对应指数相等;
        {
            temp = p->coef + q->coef;           //系数相加;
            if (fabs(temp) > 0.001)           //相加后系数不为0;
            {
                s = (Term*)malloc(sizeof(Term));
                r->link = s;
                r = r->link;
                r->coef = temp;
                r->exp = p->exp;
            }
            p = p->link;
            q = q->link;
        }
        else                                //对应项指数不等;
        {
            s = (Term*)malloc(sizeof(Term));
            r->link = s;
            r = r->link;                      //创建新项,r是C链尾指针;
            if (p->exp > q->exp)            //p指数大;
            {
                r->coef = p->coef;
                r->exp = p->exp;
                p = p->link;                  //p指向A链下一个结点;
            }
            else                            //q指数大;
            {
                r->coef = q->coef;
                r->exp = q->exp;
                q = q->link;                  //q指向B链下一个结点;
            }
        }
    }
    
    p = (p != NULL) ? p : q;                        //p指向剩余链的地址;
    
    while (p != NULL)                         //处理链剩余部分;
    {
        if (p->coef == 0)                     //如果该结点的系数为0,跳过该结点;
            p = p->link;
        else
        {
            r->link = (Term*)malloc(sizeof(Term));
            r = r->link;
            r->coef = p->coef;
            r->exp = p->exp;
            p = p->link;
        }
    }
    r->link = NULL;
}

void SUB(Polynomial& A, Polynomial& B, Polynomial& C)
{
    //计算C=A-B;
    //算法调用方式:SUB(A,B,C);
    //输入:有两个按降幂排列的多项式链表A和B,第三个多项式链表C也已经初始化;
    //输出:多项式A-B的结果存入降幂排列的多项式链表C;
    
    Polynomial p, q, r;
    p = A->link;
    q = B->link;
    r = C;
    
    while (p != NULL && q != NULL)              //两多项式未扫描完;
    {
        if (p->exp > q->exp)               //A多项式当前项指数大;
        {
            r->link = (Term*)malloc(sizeof(Term));
            r = r->link;
            r->coef = p->coef;
            r->exp = p->exp;
            p = p->link;
        }
        else if (p->exp < q->exp)          //B多项式当前项指数大;
        {
            r->link = (Term*)malloc(sizeof(Term));
            r = r->link;
            r->coef = -q->coef;
            r->exp = q->exp;
            q = q->link;
        }
        else                                //A、B当前项指数相等;
        {
            if (fabs(p->coef - q->coef) > 0.001)  //系数相减不为0存入C;
            {
                r->link = (Term*)malloc(sizeof(Term));
                r = r->link;
                r->coef = p->coef - q->coef;
                r->exp = p->exp;
            }
            p = p->link;
            q = q->link;
        }
    }

    if (p != NULL)                         //p指向A中未处理完链;
    {
        while (p != NULL)                     //处理未处理完链;
        {
            if (p->coef == 0)                 //如果该结点的系数为0,跳过该结点;
                p = p->link;
            else
            {
                r->link = (Term*)malloc(sizeof(Term));
                r = r->link;
                r->coef = p->coef;
                r->exp = p->exp;
                p = p->link;
            }
        }
        r->link = NULL;
    }
    else                                     //q指向B中未处理完链;
    {
        while (q != NULL)                     //处理未处理完链;
        {
            if (q->coef == 0)                 //如果该结点的系数为0,跳过该结点;
                q = q->link;
            else
            {
                r->link = (Term*)malloc(sizeof(Term));
                r = r->link;
                r->coef = -q->coef;
                r->exp = q->exp;
                q = q->link;
            }
        }
        r->link = NULL;
    }
}

int main(void)
{
    int n;
    printf("请输入多项式链表A的项数:");
    scanf_s("%d", &n);
    int EA[100]={0};
    double CA[100]={0.0};
    printf("请输入多项式链表A的系数和指数:");
    for (int i = 0; i < n; i++)
    {
        scanf_s("%lf %d", &CA[i], &EA[i]);
    }
    Polynomial A = NULL;            //建立链表A;
    initList(A);                    //初始化链表A;
    Input(A, CA, EA, n);            //把数组里面存的系数和指数输入链表A;
    
    int m;
    printf("请输入多项式链表B的项数:");
    scanf_s("%d", &m);
    int EB[100]={0};
    double CB[100]={0.0};
    printf("请输入多项式链表B的系数和指数:");
    for (int i = 0; i < m; i++)
    {
        scanf_s("%lf %d", &CB[i], &EB[i]);
    }
    Polynomial B = NULL;            //建立链表B;
    initList(B);                    //初始化链表B;
    Input(B, CB, EB, m);            //把数组里面存的系数和指数输入链表B;
    
    printf("多项式A(x)=");
    Output(A);
    printf("多项式B(x)=");
    Output(B);

    Polynomial C = NULL;            //建立链表C;
    initList(C);                    //初始化链表C;
    Polynomial D = NULL;            //建立链表D;
    initList(D);                    //初始化链表D;

    ADD(A, B, C);
    SUB(A, B, D);

    printf("多项式A(x)与多项式B(x)相加后得到的多项式C(x)=");
    Output(C);
    printf("多项式A(x)与多项式B(x)相减后得到的多项式D(x)=");
    Output(D);

    return 0;
}

参考文献

[1] 殷人昆作. 清华大学计算机系列教材 数据结构算法解析.[M] 北京:清华大学出版社, 2021.04.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值