《数据结构》浙大PAT 02-线性结构4 Pop Sequence

《数据结构》浙大PAT 02-线性结构4 Pop Sequence

如何判断给定的序列符不符合要求主要看两点:
①序列的顺序是否满足栈后进先出的原则,不符合则NO。
②栈的最大容量有限制,达到上限时则NO。

实际编写代码时应该如何设计:
我的思路是:首先设计一个数组,将所给的序列存放到数组中。再设计一个堆栈,待入栈的元素为1。之后从头遍历数组:每一次遍历时数组元素都是当前待出栈的元素,比较待出栈与待入栈元素的大小,如果前者大于等于后者,依据后进先出的原则,入栈,直到后者大于等于前者(若超出栈的容量,则有问题)。之后开始出栈,将数组中的待出栈元素与实际出栈的值比较(如果不相等,则说明序列的顺序有问题),从而解决问题。

下面用文字来对三个实际序列进行分析,解释算法的实现过程:
①3 2 1 7 5 6 4
第一次循环开始时:待入栈元素为1,待出栈元素为3,不断入栈,直到待入栈元素为4,此时栈内元素为1,2,3。然后开始出栈,实际出栈元素为3,等于待出栈元素,第一次循环结束;第二次循环开始时:待入栈元素为4,待出栈元素为2,此时栈内元素为1,2。开始出栈,实际出栈元素为2,等于待出栈元素,第二次循环结束;第三次循环同上;第四次循环开始时:待入栈元素为4,待出栈元素为7,不断入栈,直到待入栈元素为8,此时栈内元素为4,5,6,7。开始出栈,实际出栈元素为7,等于待出栈元素,第四次循环结束;第五次循环开始时:待入栈元素为8,待出栈元素为5,此时栈内元素为4,5,6。开始出栈,实际出栈元素为6,不等于待出栈元素5,结束循环,指定序列顺序有误;
②7 6 5 4 3 2 1
第一次循环开始时:待入栈元素为1,待出栈元素为7,不断入栈,在入栈过程中超过栈的容量,指定序列有误。
③5 6 4 3 7 2 1
第一次循环开始时:待入栈元素为1,待出栈元素为5,不断入栈,直到待入栈元素为6,此时栈内元素为1,2,3,4,5。然后开始出栈,实际出栈元素为5,等于待出栈元素,第一次循环结束;第二次循环开始时:待入栈元素为6,待出栈元素为6,入栈,直到待入栈元素为7,此时栈内元素为1,2,3,4,6。开始出栈,实际出栈元素为6,等于待出栈元素,第二次循环结束;第三次循环开始时:待入栈元素为7,待出栈元素为4,此时栈内元素为1,2,3,4。开始出栈,实际出栈元素为4,等于待出栈元素,第三次循环结束;第四次循环开始时:待入栈元素为7,待出栈元素为3,此时栈内元素为1,2,3。开始出栈,实际出栈元素为3,等于待出栈元素,第四次循环结束;第五次循环开始时:待入栈元素为7,待出栈元素为7,入栈,直到待入栈元素为8,此时栈内元素为1,2,7。开始出栈,实际出栈元素为7,等于待出栈元素,第五次循环结束;第六次循环开始时:待入栈元素为8,待出栈元素为2,此时栈内元素为1,2。开始出栈,实际出栈元素为2,等于待出栈元素,第六次循环结束;第七次循环开始时:待入栈元素为8,待出栈元素为1,此时栈内元素为1。开始出栈,实际出栈元素为1,等于待出栈元素,最后一次循环结束,所给序列顺序正确。

下面给出C语言实现的完整代码:

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

typedef struct StackNode *pNode;
struct StackNode
{
    int data;
    pNode next;
};
typedef struct StackNode *LinkStack;

void Push(LinkStack *S, int e);
int Pop(LinkStack *S);
int judge(int Maxsize, int N);

int main()
{
    int M, N, K;
    scanf("%d %d %d", &M, &N, &K);
    int *jud = (int *)malloc(K * sizeof(int));
    for (int i = 0; i < K; i++)
        jud[i] = judge(M, N);
    for (int i = 0; i < K; i++)
        if (jud[i] == 0)
            printf("NO\n");
        else
            printf("YES\n");
    return 0;
}

void Push(LinkStack *S, int e)
{
    pNode temp = (struct StackNode *)malloc(sizeof(struct StackNode));
    temp->data = e;
    temp->next = *S;
    *S = temp;
}

int Pop(LinkStack *S)
{
    int e = (*S)->data;
    pNode temp = *S;
    *S = (*S)->next;
    free(temp);
    return e;
}

int judge(int Maxsize, int N)
{
    int *arr = (int *)malloc(N * sizeof(int));
    for (int i = 0; i < N; i++)          /*申请数组,用来存放一个需要判断的序列*/
    {
        scanf("%d", &arr[i]);
    }
    int p = 1;
    int nowsize = 0;
    int flag = 1;
    LinkStack stack = NULL;
    for (int i = 0; i < N; i++)              /*该算法模拟实际的入栈出栈过程*/
    {
        while (arr[i] >= p)                  /*判断待出栈元素和未入栈元素的大小关系*/
        {
            if (nowsize == Maxsize)          
                break;                       /*栈满则退出*/
            Push(&stack, p);                 /*如果前者更大,依据后进先出的原则,需要不断入栈,直到二者相等*/
            nowsize++;
            p++;
        }
        int temp = Pop(&stack);              /*入栈结束后,开始出栈。*/
        nowsize--;
        if (arr[i] != temp)                  /*每次出栈的元素都应该等于待出栈元素,否则发生顺序错误。*/
           flag = 0;
        if (flag == 0)
            break;  
    }
    free(arr);            /*将申请的空间全部释放*/
    while (stack)
        Pop(&stack);
    return flag;
}

提交结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值