基于顺序表实现栈

本文介绍了栈作为后进先出的线性数据结构,强调了栈顶的操作,并探讨了如何使用顺序表来实现栈。文章通过实现入栈、出栈和获取栈顶元素等基本操作,展示了顺序栈的工作方式,并进行了整合测试,以减少代码冗余。

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

栈是一种后进先出(LIFO)的特殊的线性表。它限定仅在表尾进行插入或删除,表尾端被称作栈顶,表头端称作栈底。不含元素的空表称为空栈。

栈的基本操作有三个,分别为:入栈、出栈。取栈顶元素。

下面,我们先来基于顺序表实现栈,即顺序栈。

seqstack.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>

typedef char SeqStackType;

typedef struct SeqStack{
    SeqStackType *data;
    size_t size;
    size_t capacity;
}SeqStack;

void SeqStackInit(SeqStack* stack);//初始化
void SeqStackDestroy(SeqStack* stack);//销毁
void SeqStackPrint(SeqStack* stack,const char* msg);//打印
void SeqStackPush(SeqStack* stack,SeqStackType value);//入栈
void SeqStackPop(SeqStack* stack);//出栈
int GetTop(SeqStack* stack,SeqStackType* value);//取栈顶元素
seqstack.c:

#include "seqstack.h"

void SeqStackPrint(SeqStack* seqstack,const char* msg){
    printf("[%s]\n",msg);
    size_t i = 0;
    for(;i < seqstack->size;i++){
        printf("[%c] ",seqstack->data[i]);
    }
    printf("\n");
}

void SeqStackInit(SeqStack* seqstack){
    if(seqstack == NULL){
        return;
    }
    seqstack->size = 0;
    seqstack->capacity = 1024;
    seqstack->data = (SeqStackType*)malloc(seqstack->capacity * sizeof(SeqStackType));
}

void SeqStackDestroy(SeqStack* seqstack){
    if(seqstack == NULL){
        return;
    }
    free(seqstack->data);
    seqstack->size = 0;
    seqstack->capacity = 0;
}

void SeqStackResize(SeqStack* seqstack){
    if(seqstack == NULL){
        return;
    }
    if(seqstack->size < seqstack->capacity){
        return;
    }
    SeqStackType* new_ptr = (SeqStackType*)malloc(seqstack->capacity*sizeof(SeqStackType)*2+1);
    size_t i =0;
    //搬运原来的数据
    for(;i < seqstack->size;i++){
        new_ptr[i] = seqstack->data[i];
    }
    free(seqstack->data);
    seqstack->data = new_ptr;
}

void SeqStackPush(SeqStack* seqstack,SeqStackType value){
    if(seqstack == NULL){
        return;
    }
    if(seqstack->size >= seqstack->capacity){
        SeqStackResize(seqstack);
    }
    seqstack->data[seqstack->size++] = value;
}

void SeqStackPop(SeqStack* seqstack){
    if(seqstack == NULL){
      //非法输入
        return;
    }
    if(seqstack->size == 0){
        return;
    }
    --seqstack->size;
    return;
}

int GetTop(SeqStack* seqstack,SeqStackType* value){
    if(seqstack == NULL || value == 0){
        return 0;
    }
    if(seqstack->size == 0){
        return 0;
    }
    //不能--size,会把size的值修改
    *value = seqstack->data[seqstack->size-1];
    return 1;
}
test.c:

#include "seqstack.h"

#define PRINT_HEADER printf("\n============%s============\n",__FUNCTION__)

void test(){
    PRINT_HEADER;
    SeqStack stack;
    SeqStackInit(&stack);
    printf("size except 0,actual %lu\n",stack.size);
    printf("capacity except 1024,except %lu\n",stack.capacity);
    SeqStackPrint(&stack,"顺序栈的初始化");

    SeqStackPush(&stack,'a');
    SeqStackPush(&stack,'b'); 
    SeqStackPush(&stack,'c'); 
    SeqStackPush(&stack,'d');
    SeqStackPrint(&stack,"入栈四个元素");
    
    SeqStackPop(&stack);
     SeqStackPrint(&stack,"出栈一个元素");
    SeqStackPop(&stack);
    SeqStackPrint(&stack,"出栈两个元素");
    SeqStackPop(&stack);
     SeqStackPrint(&stack,"出栈三个元素");
    SeqStackPop(&stack);
    SeqStackPrint(&stack,"出栈四个元素");
    SeqStackPop(&stack);
    SeqStackPrint(&stack,"尝试对空栈进行出栈操作");

    SeqStackPush(&stack,'a');
    SeqStackPush(&stack,'b'); 
    SeqStackPush(&stack,'c'); 
    SeqStackPush(&stack,'d');
    SeqStackPrint(&stack,"入栈四个元素");

    SeqStackType value;
    int ret = GetTop(&stack,&value);
    printf("ret expect 1,actual %d\n",ret);
    printf("top except d,actual %c\n",value);

    SeqStackDestroy(&stack);
    SeqStackPrint(&stack,"销毁栈");
}

int main(){
    test();
}

由于栈的操作相对较少,所以我们就将测试放到了一起,而并没有分别对每个函数进行测试,这样不仅较少了代码量,也减少了代码的重复性。

结果演示:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值