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\n", list[i], Data[list[i]], list[i + 1]);
    printf("%05d %d -1\n", 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\n");
        else    printf("NO\n");
    }
    
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值