数据结构之顺序栈——C语言实现

一、代码注释

1.相关头文件

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

malloc.h :malloc()realloc()

malloc()用于初始化栈,realloc()用于栈内存不足时扩容

stdlib.h
stdio.h:
stdbool.h:bool类型变量

2.宏定义内容

//根据使用的具体情况修改
#define SElemType int
#define SElemType_Flag "int"
#define SFormat "%d\t"
#define SPath ""

SElemType:栈中元素类型
SElemType_Flag:用于初始化告知栈中元素类型
SFormat "%d\t":用于遍历打印/追踪栈运行进程/写入文件的格式
SPath:用于遍历栈中元素写入文件

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

STACK_INIT_SIZE:初始化栈的规模
STACKINCREMENT:每次栈内存不足时扩容的规模

#define SDisplayFlag 1

DisplayFlag:用于程序运行追踪

3.可读性优化及栈类型声明

typedef bool Status;
typedef struct SqStack
{
    SElemType *base;
    SElemType *top;
    int stacksize;
} SqStack;

4.相关函数

1)void InitStack(SqStack *S);初始化顺序栈

void InitStack(SqStack *S)
{
    S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S->base)
    {
        printf("顺序栈初始化失败");
        exit(1);
    }
    S->top = S->base;
    S->stacksize = STACK_INIT_SIZE;
    printf("顺序栈初始化完成\n");
    printf("栈中元素为" SElemType_Flag "类型\n");
}

2)void DestroyStack(SqStack *S);销毁栈

void DestroyStack(SqStack *S)
{
    free(S->base);
    S->stacksize = 0;
    S->base = S->top = NULL;
}

3)void ClearStack(SqStack *S);清空栈

void ClearStack(SqStack *S)
{
    S->top = S->base;
}

4)Status StackEmpty(SqStack S);判断栈空

Status StackEmpty(SqStack S)
{
    if (S.top == S.base)
        return true;
    else
        return false;
}

5)Status StackFull(SqStack S);判断栈满

Status StackFull(SqStack S)
{
    if (S.top - S.base == S.stacksize)
        return true;
    else
        return false;
}

6)int StackLength(SqStack S);返回栈长

int StackLength(SqStack S)
{
    return S.top - S.base;
}

7)SElemType GetStackTop(SqStack S);返回栈顶元素

SElemType GetStackTop(SqStack S)
{
    if (StackEmpty(S)) // 栈空
    {
        printf("取栈顶元素错误:顺序栈为空");
        exit(1);
    }
    else
    {
	    if (SDisplayFlag)
	        printf("栈顶元素:" SFormat, *(S.top - 1));
        return *(S.top - 1);
    }
        
}

8)void Push(SqStack *S, SElemType e);压栈

插入元素e为新的栈顶元素

void Push(SqStack *S, SElemType e)
{
    if (StackFull(*S)) // 栈满
    {
        S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
        if (!S->base)
        {
            printf("顺序栈增加容量错误");
            exit(1);
        }
        S->top = S->base + S->stacksize;
        S->stacksize += STACKINCREMENT;
    }
    *S->top++ = e; //=*(S->top)=e;S->top++;
    if (SDisplayFlag)
        printf("压栈:" SFormat, e);
}

9)void Pop(SqStack *S, SElemType *e);弹栈

删除S的栈顶元素,并用e返回其值

void Pop(SqStack *S, SElemType *e)
{
    if (StackEmpty(*S)) // 栈空
    {
        printf("弹栈错误:顺序栈为空");
        exit(1);
    }
    else
        *e = *--S->top; //=--S->top;e = *(S->top);
    if (SDisplayFlag)
        printf("弹栈:" SFormat, *e);
}

10)void StackTraverse(SqStack S, void *visit(SElemType));遍历栈元素

从栈底到栈顶依次对S的每个元素调用函数visit()

void StackTraverse(SqStack S, void visit(SElemType))
{
    if (StackEmpty(S)) // 栈空
    {
        printf("栈遍历错误:顺序栈为空");
        exit(1);
    }
    SElemType *temp = S.base;
    printf("栈中共%d个元素:\n", StackLength(S));
    while (temp != S.top)
    {
        visit(*temp);
        temp++;
    }
    if (SPath == "")
	    printf("\n");
	else
	{
		FILE *fp = fopen(SPath, "a");
		fprintf(fp,"\n");
		fclose(fp);
	}
}
void PrintSElem(SElemType e)
{
    printf(SFormat, e);
}
void FPrintSElem(SElemType e)
{
	FILE *fp = fopen(SPath,"a");
	fprintf(fp,SFormat,e);
	fclose(fp);
}

二、完整代码

/*
名称:SqStack.h
内容:顺序栈相关操作
创建者:尘
最近更新时间:2023年10月26日16:04:36
修改:
#define SElemType 
#define SElemType_Flag 
#define Format 
#define Path 
*/

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

// 根据使用的具体情况修改
// 栈中数据类型及打印格式
#ifndef SElemType
#define SElemType int
#endif
#ifndef SElemType_Flag
#define SElemType_Flag "int"
#endif
#ifndef SFormat
#define SFormat "%d\t"
#endif
#ifndef SPath
#define SPath ""
#endif

// 顺序栈的规模
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

// 便于程序运行追踪
#define SDisplayFlag 0

#ifndef Status
typedef bool Status;
#endif
typedef struct SqStack
{
    SElemType *base;
    SElemType *top;
    int stacksize;
} SqStack;

void InitStack(SqStack *S)
{
    S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S->base)
    {
        printf("顺序栈初始化失败");
        exit(1);
    }
    S->top = S->base;
    S->stacksize = STACK_INIT_SIZE;
    printf("顺序栈初始化完成\n");
    printf("栈中元素为" SElemType_Flag "类型\n");
}

void DestroyStack(SqStack *S)
{
    free(S->base);
    S->stacksize = 0;
    S->base = S->top = NULL;
}

void ClearStack(SqStack *S)
{
    S->top = S->base;
}
Status StackEmpty(SqStack S)
{
    if (S.top == S.base)
        return true;
    else
        return false;
}
Status StackFull(SqStack S)
{
    if (S.top - S.base == S.stacksize)
        return true;
    else
        return false;
}
int StackLength(SqStack S)
{
    return S.top - S.base;
}
SElemType GetStackTop(SqStack S)
{
    if (StackEmpty(S)) // 栈空
    {
        printf("取栈顶元素错误:顺序栈为空");
        exit(1);
    }
    else
    {
        if (SDisplayFlag)
            printf("栈顶元素:" SFormat, *(S.top - 1));
        return *(S.top - 1);
    }
}
void Push(SqStack *S, SElemType e)
{
    if (StackFull(*S)) // 栈满
    {
        S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
        if (!S->base)
        {
            printf("顺序栈增加容量错误");
            exit(1);
        }
        S->top = S->base + S->stacksize;
        S->stacksize += STACKINCREMENT;
    }
    *S->top++ = e; //=*(S->top)=e;S->top++;
    if (SDisplayFlag)
        printf("压栈:" SFormat, e);
}
void Pop(SqStack *S, SElemType *e)
{
    if (StackEmpty(*S)) // 栈空
    {
        printf("弹栈错误:顺序栈为空");
        exit(1);
    }
    else
        *e = *--S->top; //=--S->top;e = *(S->top);
    if (SDisplayFlag)
        printf("弹栈:" SFormat, *e);
}
void StackTraverse(SqStack S, void visit(SElemType))
{
    if (StackEmpty(S)) // 栈空
    {
        printf("栈遍历错误:顺序栈为空");
        exit(1);
    }
    SElemType *temp = S.base;
    printf("栈中共%d个元素:\n", StackLength(S));
    while (temp != S.top)
    {
        visit(*temp);
        temp++;
    }
    if (SPath == "")
        printf("\n");
    else
    {
        FILE *fp = fopen(SPath, "a");
        fprintf(fp, "\n");
        fclose(fp);
    }
}
void PrintSElem(SElemType e)
{
    printf(SFormat, e);
}
void FPrintSElem(SElemType e)
{
    FILE *fp = fopen(SPath, "a");
    fprintf(fp, SFormat, e);
    fclose(fp);
}

三、总结

学习过程中手敲的顺序栈相关操作,便于后续偷懒使用不是,如果大家发现有什么bug,欢迎评论指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值