PTA浙江大学数据结构习题——第二周

简介: PTA浙江大学数据结构习题——第二周

第二周

两个有序链表序列的合并

List Merge( List L1, List L2 )
{
    List L3 = (List)malloc(sizeof(struct Node));
    List p3 = L3;
    List p1 = L1->Next, p2 = L2->Next;
    while (p1 && p2)
    {
        if (p1->Data <= p2->Data)
        {
            p3->Next = p1;
            p1 = p1->Next;
        }
        else
        {
            p3->Next = p2;
            p2 = p2->Next;
        }
        p3 = p3->Next;
    }
    if (p1) p3->Next = p1;
    else    p3->Next = p2;
    L1->Next = NULL, L2->Next = NULL;
    return L3;
}

一元多项式的乘法与加法运算

#include <iostream>
using namespace std;
typedef struct PolyNode* Polynomial;
struct PolyNode
{
    int coef;
    int expon;
    Polynomial next;
};
// 输出表达式
void output(Polynomial list)
{
    Polynomial cur = list;
    int cnt = 0;
    // 如果该多项式是零多项式,则输出 0 0
    if (list->next == NULL) printf("0 0");
    while (cur->next != NULL)
    {
        cur = cur->next;
        if (!cnt)   printf("%d %d", cur->coef, cur->expon);
        else printf(" %d %d", cur->coef, cur->expon);
        cnt ++;
    }
}
// 读取表达式链表
Polynomial read()
{
    Polynomial list = (Polynomial)malloc(sizeof(struct PolyNode));
    list->next = NULL;
    int len;
    scanf("%d", &len);
    Polynomial cur = list;
    while (len --)
    {
        Polynomial p = (Polynomial)malloc(sizeof(struct PolyNode));
        scanf("%d%d", &(p->coef), &(p->expon));
        p->next = NULL;
        cur->next = p;
        cur = p;
    }
    return list;
}
// 计算两式之和
Polynomial compute_sum(Polynomial list1, Polynomial list2)
{
    Polynomial list = (Polynomial)malloc(sizeof(struct PolyNode));
    list->next = NULL;
    Polynomial p = list, p1 = list1->next, p2 = list2->next;
    while (p1 && p2)
    {
        Polynomial cur = (Polynomial)malloc(sizeof(struct PolyNode));
        cur->next = NULL;
        if (p1->expon > p2->expon)
        {
            cur->coef = p1->coef;
            cur->expon = p1->expon;
            p->next = cur;
            p = cur;
            p1 = p1->next;
        }
        else if (p1->expon < p2->expon)
        {
            cur->coef = p2->coef;
            cur->expon = p2->expon;
            p->next = cur;
            p = cur;
            p2 = p2->next;
        }
        else
        {
            if (p1->coef + p2->coef != 0)
            {
                cur->coef = p1->coef + p2->coef;
                cur->expon = p1->expon;
                p->next = cur;
                p = cur;
            }
            p1 = p1->next, p2 = p2->next;
        }
    }
    while (p1)
    {
        Polynomial cur = (Polynomial)malloc(sizeof(struct PolyNode));
        cur->next = NULL;
        cur->coef = p1->coef, cur->expon = p1->expon;
        p->next = cur;
        p = cur;
        p1 = p1->next;
    }
    while (p2)
    {
        Polynomial cur = (Polynomial)malloc(sizeof(struct PolyNode));
        cur->next = NULL;
        cur->coef = p2->coef, cur->expon = p2->expon;
        p->next = cur;
        p = cur;
        p2 = p2->next;
    }
    return list;
}
// 计算两式乘积
Polynomial compute_prod(Polynomial list1, Polynomial list2)
{
    Polynomial list = (Polynomial)malloc(sizeof(struct PolyNode));
    list->next = NULL;
    Polynomial p1 = list1->next, p2 = list2->next;
    // 每次用list1的一个结点和list2所有结点相乘
    while (p1)
    {
        Polynomial cur_head = (Polynomial)malloc(sizeof(struct PolyNode)); // 相乘得到的链表
        Polynomial p = cur_head;
        p2 = list2->next;
        while (p2)
        {
            Polynomial cur = (Polynomial)malloc(sizeof(struct PolyNode));
            cur->coef = p1->coef * p2->coef;
            cur->expon = p1->expon + p2->expon;
            p->next = cur;
            p = cur;
            p2 = p2->next;
        }
        // 至少要先乘一次,才能做加法
        if (!list->next) list = cur_head;
        else    list = compute_sum(list, cur_head);
        p1 = p1->next;
    }
    return list;
}
int main()
{
    Polynomial list1 = read();
    Polynomial list2 = read();
    Polynomial prod = compute_prod(list1, list2);
    output(prod);
    puts("");
    Polynomial sum = compute_sum(list1, list2);
    output(sum);
    return 0;
}

Reversing Linked List

Data 数组记录 address 下的值,Next 数组记录下一个地址,list 数组按顺序记录存放的数值。

根据 k 值和 list 长度对 list 子数组进行翻转,注意这里 list 的长度 sum 和输入的长度 len 可能不同。

#include <iostream>
using namespace std;
const int N = 100010;
int Data[N], Next[N], list[N];
int start, len, k;
int main()
{
    scanf("%d%d%d", &start, &len, &k);
    for (int i = 0; i < len; i ++)
    {
        int address, tmpData, tmpNext;
        scanf("%d %d %d", &address, &tmpData, &tmpNext);
        Data[address] = tmpData, Next[address] = tmpNext;
    }
    // 地址原顺序
    int sum = 0;
    while (start != -1)
    {
        list[sum ++] = start;
        start = Next[start];
    }
    // 每k个元素翻转1次地址顺序
    for (int i = 0; i < sum - sum % k; i += k)
        for (int j = 0; j < k / 2; j ++)
            swap(list[i + j], list[i + k - j - 1]);
    // 输出地址和元素值
    for (int i = 0; i < sum - 1; i ++)
        printf("%05d %d %05d
", list[i], Data[list[i]], list[i + 1]);
    printf("%05d %d -1
", list[sum - 1], Data[list[sum - 1]]);
    return 0;
}

Pop Sequence

直接模拟,按 1~N 的顺序入栈,若当前栈顶元素符合当前出栈元素 s[cur] ,就先出栈,然后再继续入栈。

如果最终 cur 不为 n + 1,就说明不能按照 s 数组中的顺序出栈,输出 NO;否则可以,输出 YES。

#include <iostream>
using namespace std;
const int N = 1010;
int stack[N], s[N], top;
int m, n, k;
int main()
{
    scanf("%d%d%d", &m, &n, &k);
    while (k --)
    {
        top = -1;
        int cur = 1;
        for (int i = 1; i <= n; i ++)    scanf("%d", &s[i]);
        for (int i = 1; i <= n; i ++)
        {
          // 入栈
            stack[++ top] = i;
            // 栈满
            if (top >= m)    break;
            // 出栈
            while (top != -1 && stack[top] == s[cur])
            {
                top --;
                cur ++;
            }
        }
        // 合法出栈n次,表示该序列合法
        if (cur == n + 1)   printf("YES
");
        else    printf("NO
");
    }
    return 0;
}


相关文章
数据结构之栈的讲解(源代码+图解+习题)
我们在学习过顺序表和链表之后,了解了使用数组存储数据,使用结构体来存储数据和有关的指针,这些都是底层的东西,链表是靠指针的链接,顺序表是靠数组的下标才能得以实现增删查改。众多数据结构其实底层都离不开数组,指针和结构体,今天我们要学习的栈也不例外,话不多说,直接上正菜!
数据结构之栈的讲解(源代码+图解+习题)
|
C语言
数据结构pta训练题-编程题1(1)
数据结构pta训练题-编程题
143 0
|
25天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
26 7
|
5月前
|
算法
数据结构和算法学习记录——习题-移除链表元素
数据结构和算法学习记录——习题-移除链表元素
24 0
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
42 2
|
5月前
|
存储 算法 测试技术
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
78 1
|
5月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
46 1
|
5月前
|
机器学习/深度学习
数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)
数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)
38 1
|
5月前
|
算法
数据结构和算法学习记录——小习题-二叉树的遍历&二叉搜索树
数据结构和算法学习记录——小习题-二叉树的遍历&二叉搜索树
37 0