浙江大学MOOC数据结构-陈越、何钦铭 编程练习题(第二讲)

本文提供浙江大学MOOC数据结构课程的编程练习题解答,包括链表合并、多项式运算、链表逆序和模拟栈操作等题目,涉及C语言编程实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浙江大学MOOC数据结构-陈越、何钦铭 编程练习题(第二讲)

在这里插入图片描述

编程说明

编程环境:平台运行
编程语言:C

第一题代码

//链表:每一个节点对应一个结构体
List Merge( List L1, List L2 )
{
    List p1,p2,p,L;
    p1=L1->Next;//L1指向头节点,头节点的L1->next对应首元节点。故p1指向L1链表首元节点
    p2=L2->Next;//L2指向头节点,头节点的L2->next对应首元节点。故p2指向L2链表首元节点

    L=(List)malloc(sizeof(List));//创建L链表,默认指向头节点
    L->Data=L1->Data+L2->Data;//L链表头节点的数据=L1链表头节点的数据+L2链表头节点的数据
    p=L;//p指向L链表的头节点

    while(p1!=NULL&&p2!=NULL)
    {
        if(p1->Data < p2->Data)
        {
            p->Next=p1;
            p=p->Next;
            p1=p1->Next;
        }
        else
        {
            p->Next=p2;
            p=p->Next;
            p2=p2->Next;
        }
    }

    if(p1==NULL)
        p->Next=p2;
    else if(p2==NULL)
        p->Next=p1;

    L1->Next=NULL;
    L2->Next=NULL;

    return L;
}

第二题程序代码

#include <stdio.h>
#include <stdlib.h>

typedef struct PolyNode *Polynomial;
struct PolyNode {
        int coef;
        int expon;
        Polynomial link;
};
Polynomial ReadPoly();
void Attach(int,int,Polynomial*);
Polynomial Mult(Polynomial,Polynomial);
Polynomial Add(Polynomial,Polynomial);
void PrintPoly(Polynomial);

int main()
{
    Polynomial P1, P2, PP, PS;
    P1 = ReadPoly();
    P2 = ReadPoly();
    PP = Mult( P1, P2 );
    PrintPoly( PP );
    PS = Add( P1, P2 );
    PrintPoly( PS );

    return 0;
}

Polynomial ReadPoly()
{
    Polynomial Rear,P,t;
    int c,e,N;
    scanf("%d",&N);

    //Rear是存放数据的链表节点(头到末),P是链表的头节点后经修改为首元节点,t便于释放头节点
    P = (Polynomial)malloc(sizeof(struct PolyNode));//链表头空节点
    P->link=NULL;
    Rear=P;
    for(int i=0;i<N;i++)
    {
        scanf("%d %d",&c,&e);
        Attach(c,e,&Rear);
    }

    t=P;//t临时指针指向头节点P
    P=P->link;//P后移指向首元节点
    free(t);//释放头节点

    return P;
}

void Attach(int c,int e,Polynomial *pRear)
{
    Polynomial P;
    P = (Polynomial)malloc(sizeof(struct PolyNode));//链表存放数据都需要新开辟空间

    P->coef=c;
    P->expon=e;
    P->link=NULL;

    (*pRear)->link=P;//把新空间链接到原链表后面
    *pRear=P;//把链表的指针移动到新开辟的空间
}

Polynomial Mult(Polynomial P1,Polynomial P2 )
{
    Polynomial P,Rear,t1,t2,t;
    int c,e;

    if(!P1||!P2)
        return NULL;

    t1=P1;
    t2=P2;

    P = (Polynomial)malloc(sizeof(struct PolyNode));//链表存放数据都需要新开辟空间
    P->link=NULL;
    Rear=P;

	//多项式1第一项乘以多项式2的每一项
    while(t2)
    {
        Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
        t2=t2->link;
    }

	//多项式1的每一项(无第一项)乘以多项式2的每一项
    t1=t1->link;
    while(t1)
    {
        t2=P2;//多项式2从头开始
        Rear=P;//每一次需要从mult链表头节点开始,为了指数降序排列
        while(t2)
        {
            c=t1->coef*t2->coef;
            e=t1->expon+t2->expon;
            while(Rear->link&&Rear->link->expon>e)//mutl链表下一节点项非空,且计算得到的新项指数比前面的项指数都低,则需要一直往后排,mult链表指针后移
                Rear=Rear->link;
            if(Rear->link&&Rear->link->expon==e)//计算项与链表下一项指数相同
            {
                if(c+Rear->link->coef)//系数非0,只改系数
                {
                    Rear->link->coef+=c;
                }
                else//系数0则需要释放节点
                {
                    t=Rear->link;
                    Rear->link=t->link;
                    free(t);
                }
            }
            else//计算项指数最大,需要新建节点插入
            {
                t = (Polynomial)malloc(sizeof(struct PolyNode));
                t->coef=c;
                t->expon=e;
                
                t->link=Rear->link;
                Rear->link=t;
                Rear=Rear->link;
            }
            t2=t2->link;
        }
        t1=t1->link;
    }

	//t2用于删除头节点
    t2=P;
    P=P->link;
    free(t2);

    return P;
}
//为什么不直接链表P链接,因为有加和乘两操作,不可以改变原始数据
Polynomial Add(Polynomial P1,Polynomial P2 )
{
    Polynomial Rear,front,temp;

    Rear = (Polynomial)malloc(sizeof(struct PolyNode));//链表存放数据都需要新开辟空间,Rear用于链表数据存放
    front=Rear;//front用于记录链表起始地址,便于后面返回链表首地址

    while(P1!=NULL && P2!=NULL)
    {
        if(P1->expon>P2->expon)
        {
            Attach(P1->coef,P1->expon,&Rear);
            P1=P1->link;
        }
        else if(P1->expon<P2->expon)
        {
            Attach(P2->coef,P2->expon,&Rear);
            P2=P2->link;
        }
        else
        {
            if((P1->coef+P2->coef)!=0)//系数不等于0,此项才添加到新链表
            {
                Attach(P1->coef+P2->coef,P1->expon,&Rear);
            }

            P1=P1->link;
            P2=P2->link;
        }
    }

    for(;P1;P1=P1->link)
    {
        Attach(P1->coef,P1->expon,&Rear);
    }
    for(;P2;P2=P2->link)
    {
        Attach(P2->coef,P2->expon,&Rear);
    }

    Rear->link=NULL;

	//temp用于删去头节点
    temp=front;
    front=front->link;
    free(temp);

    return front;
}

//打印的时候,第一次只打印数据,之后:空格+数据
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");
}

第三题代码

https://blog.youkuaiyun.com/liuchuo/article/details/51985857?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-13&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-13

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

int main()
{
    int first, k, n, sum = 0;
    cin >> first >> n >> k;
    int temp, data[100005], next[100005], list[100005], result[100005];

    for (int i = 0; i < n; i++) {
        cin >> temp;
        cin >> data[temp] >> next[temp];
    }

    while (first != -1) {
        list[sum++] = first;
        first = next[first];
    }

    for (int i = 0; i < sum; i++)
        result[i] = list[i];

    //i决定了几个需要逆向翻转。k-1-i%k是一个小阶段逆向组的下标位置。i/k*k是前面的组数*一组元素数
    for (int i = 0; i < (sum - sum % k); i++)
        result[i] = list[i / k * k + k - 1 - i % k];

    for (int i = 0; i < sum - 1; i++)
        printf("%05d %d %05d\n", result[i], data[result[i]], result[i + 1]);
    printf("%05d %d -1", result[sum - 1], data[result[sum - 1]]);

    return 0;
}

第四题代码

这里是引用https://blog.youkuaiyun.com/weixin_44720323/article/details/102502803

#include <stdio.h>
#include <stdlib.h>

//堆栈定义
typedef int ElementType;
typedef struct SNode *Stack;
struct SNode{
    ElementType Data;
    Stack Next;
};

//函数声明
Stack CreateStack();
int IsEmpty(Stack S);
void Push( ElementType item, Stack S);
ElementType Pop(Stack S);
int GetTop(Stack p);
int **ReadData(int m,int n,int k);

int main()
{
    int m,n,k;
    int **ptr;
    scanf("%d%d%d",&m,&n,&k);
    ptr = ReadData(m,n,k);

    for(int i=0;i<k;i++)
    {   //真正的模拟了栈
        //i的数值每一次代表预先输入数组的一行。
        Stack p = CreateStack();
        int count = 0; //记录栈的容量
        int current = 0; //记录要检测数组下标
        for(int j=1;j<=n;j++)
        {
            Push(j,p);
            count++;
            if(count > m)
                break;
            while(!IsEmpty(p) && GetTop(p) == ptr[i][current])// p非空 && 栈顶元素等于预先输入数组
            {
                Pop(p);
                count--;
                current++;
            }
        }
        while(!IsEmpty(p))
            Pop(p);
        if(current == n)
            printf("YES\n");
        else
            printf("NO\n");
    }

    for(int j=0;j<k;j++)
    { //为每一行分配地址
        free(*(ptr+j));
    }

    system("pause");

    return 0;
}


//头节点S,S->Next指向栈顶
Stack CreateStack()
{   /* 构建一个堆栈的头结点,返回指针 */
    Stack S;
    S =(Stack)malloc(sizeof(struct SNode));
    S->Next = NULL;
    return S;
}

int IsEmpty(Stack S)
{   /*判断堆栈S是否为空, 若为空函数返回整数1, 否则返回0 */
    return ( S->Next == NULL );
}

void Push( ElementType item, Stack S)
{   /* 将元素item压入堆栈S */
    Stack TmpCell;
    TmpCell=(Stack)malloc(sizeof(struct SNode));
    TmpCell->Data = item;
    TmpCell->Next = S->Next;
    S->Next = TmpCell;
}

ElementType Pop(Stack S)
{   /* 删除并返回堆栈S的栈顶元素 */
    Stack FirstCell;
    ElementType TopElem;
    if( IsEmpty( S ) ) {
        printf("堆栈空");
        return NULL;
    }
    else {
        FirstCell = S->Next;
        S->Next = FirstCell->Next;
        TopElem = FirstCell ->Data;
        free(FirstCell);
        return TopElem;
    }
}

int GetTop(Stack p)
{
    return p->Next->Data;
}

int **ReadData(int m,int n,int k) //读取数据
{
    int num;
    int **arr;
    arr = (int**)malloc(sizeof(int*)*(k));
    for(int j=0;j<k;j++){ //为每一行分配地址
        arr[j] = (int*)malloc(sizeof(int)*n);
    }
    for(int i=0;i<k;i++){
        for(int j=0;j<n;j++){
            scanf("%d",&num);
            arr[i][j] = num;
        }
    }
    return arr;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值