PTA 反向输出整数序列(动态分配栈)

题目描述

输入一个整数序列(非负整数,只含 正整数 和 0 )。序列以 -1 结束。要求反向输出这个非负整数序列。

要求定义一个栈来实现这个程序的功能。

输入

一个整数序列,每个数之间以空格隔开,非负整数,只含 正整数 和 0 。输入-1 表示输入结束。

输出

反向输出这个非负整数序列。

提示:

1、在C语言程序中使用 bool 类型,必须包含头文件 stdbool.h

2、题目要求创建栈时,栈空间有16个存储单元。但是服务器测试数据有超过50万个数据需要输入。因此,要求Push操作检查当前存储空间是否已满。若当前存储空间已满,则需要把容量(capacity)扩大为原来容量的2倍。

3、在Pop操作中,也要求检查容量。若弹出1个元素后,已用空间只有容量的三分之一,把容量减少为原来容量的一半。

函数接口定义:

栈的定义如下:

typedef int ElemType;

struct StackRecord;
typedef struct StackRecord *Stack;

struct StackRecord
{
    ElemType  *base;  //指向栈的元素存储空间
    int     top;      // 栈顶
    int   capacity;   //  当前已分配空间,以元素为单位
};


写出 createStack,push, pop,top,empty,destroy函数的定义。函数声明如下:

Stack createStack(void); //初始化一个空栈。空栈拥有16个元素的空间,栈顶值为 -1

void push(Stack pStack, ElemType x);//把 x 入栈

ElemType top(Stack pStack);//返回当前栈顶元素的值

void pop(Stack pStack); //当前栈顶元素出栈

bool empty(Stack pStack);//如果栈空,则返回 true,否则返回 false

void destroy(Stack pStack);//清空分配给栈的存储空间

裁判测试程序样例:

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

typedef int ElemType;

struct StackRecord;
typedef struct StackRecord *Stack;

struct StackRecord
{
    ElemType  *base;  //指向栈的元素存储空间
    int     top;      // 栈顶
    int   capacity;   //  当前已分配空间,以元素为单位
};

Stack createStack();
void push(Stack pStack, ElemType x);
void pop(Stack pStack);
ElemType top(Stack pStack);
bool empty(Stack pStack);
void destroy(Stack pStack);

int main(void)
{
    Stack pStack;
    pStack = createStack();
    int x;
    scanf("%d", &x);
    while (x != -1)
    {
        push(pStack, x);
        scanf("%d", &x);
    }
    while (!empty(pStack))
    {
        x = top(pStack);
        printf("%d ", x);
        pop(pStack);
    }
    destroy(pStack);
    return 0;
}
/* 请在这里填写答案 */

按照题目要求,需要我们对栈的大小进行重新分配,确保栈能够处理动态调整大小,并有效管理内存。所以需要调用realloc函数

声明

下面是 realloc() 函数的声明:

void *realloc(void *ptr, size_t size)

参数

  • ptr -- 指针指向一个要重新分配内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
  • size -- 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。

返回值

  • 如果成功,realloc() 返回指向新内存块的指针。
  • 如果失败,返回 NULL,并且原来的内存块仍然保持不变(并没有释放)。

使用说明

  • realloc() 可能会将内存块移动到新的位置(如果在原位置没有足够的空间容纳新的大小)。如果移动成功,ptr 会指向新位置。需要特别注意,旧的 ptr 指针需要被更新为 realloc() 返回的新地址。
  • 如果内存分配失败,realloc() 返回 NULL,而原始的内存块不会被释放。为避免内存泄漏,应该使用一个临时指针来接收 realloc() 的返回值,并检查是否为 NULL。

下面是各个函数的实现: 

Stack createStack(void):

Stack createStack(void){
    Stack s=(Stack)malloc(sizeof(Stack));//分配内存给栈的结构体
    s->capacity=16;//初始化栈的最大容量
    s->base=(ElemType*)malloc(sizeof(ElemType)*s->capacity);//分配栈存储的元素空间
    s->top=-1;//初始化栈顶指针
    return s;//返回栈s的指针
}

void push(Stack s,ElemType x):

void push(Stack s,ElemType x){
    if(s->top+1==s->capacity){//判断是否栈满
        s->capacity*=2;//更新栈的最大容量
        s->base=(ElemType*)realloc(s->base,sizeof(ElemType)*s->capacity);
        //对栈进行重新分配内存空间,并返回分配后的指针
    }
    s->base[++s->top]=x;//栈顶指针自增,将元素压入栈顶
}

ElemType top(Stack s):

ElemType top(Stack s){
    return s->base[s->top--];
    //返回栈顶元素
}

void pop(Stack s):

void pop(Stack s){
    if(s->top+1<=s->capacity/3&&s->capacity>16){
        //判断栈的元素数量是否小于最大容量的三分之一
        s->capacity/=2;//更新栈的最大容量
        s->base=(ElemType*)realloc(s->base,sizeof(ElemType)*s->capacity);
        //对栈进行重新分配内存空间,并返回分配后的指针
    }
}

bool empty(Stack s):

bool empty(Stack s){
    return s->top==-1;//当栈顶指针为-1时返回1,程序判断栈空
}

void destroy(Stack s):

void destroy(Stack s){
    //释放内存空间
    free(s->base);
    free(s);
}//有malloc,calloc,realloc养成习惯释放内存,避免内存泄露

提交: 

这道题主要考察realloc函数的调用和栈的初始化,realloc需要更新可能改变的指针地址。注意释放内存。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值