数据结构:栈的实现

本文介绍了栈这种特殊线性表的数据结构,强调了其后进先出(LIFO)原则,并通过羽毛球筒和吃东西的例子说明了生活中的栈实例。接着详细阐述了栈的动态实现,包括初始化、检查栈容量、入栈、出栈、获取栈顶元素、获取元素个数、判断栈空和销毁栈等操作。最后提到了代码组织结构,包含Stack.c、test.c和Stack.h三个源文件。
摘要由CSDN通过智能技术生成

栈的结构和概念
栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端成为栈顶,另一端称为栈底,栈中元素遵循先出后进的顺序
压栈:插入元素
出栈:删除元素
在这里插入图片描述
生活中栈的实例:羽毛球筒,吃东西吐出来等等。

栈的实现

实现栈的相关功能时,由于栈的特性我们进行分析后,栈的底层结构可以形成一段连续的空间,可对其进行尾插尾删的操作。

这里我们实现的是支持动态增长的栈结构,静态栈结构不常用到
在这里插入图片描述

(1)初始化栈

void StackInit(Stack* ps)// 初始化栈 
{
	assert(ps);
	ps->array = (STDataType*)malloc(sizeof(STDataType) * 10);
	if (NULL == ps->array)
	{
		assert(0);
		return;
	}
	ps->capacity = 10;
	ps->top = 0;
}

(2)检查栈容量

void CheckCapacity(Stack* ps)//检查容量
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		//1.开辟新空间
		STDataType* newCapacity = (STDataType*)malloc(sizeof(STDataType)*ps->top * 2);
		if (newCapacity == NULL)
		{
			assert(0);
			return;
		}
		//2.拷贝元素
		memcpy(newCapacity, ps->array, sizeof(STDataType)*ps->top);

		//3.释放旧空间
		free(ps->array);

		//4.使用新空间
		ps->array = newCapacity;
		ps->capacity *= 2;
	}
}

(3)入栈
相当于顺序表中的尾插操作

void StackPush(Stack* ps, STDataType data)// 入栈 
{
	assert(ps);
	CheckCapacity(ps);
	ps->array[ps->top++] = data;
}

(4)出栈
相当于顺序表中的尾删操作

void StackPop(Stack* ps)// 出栈 
{
	if (StackEmpty(ps))
		return;

	ps->top--;
}

(5)获取栈顶元素操作

STDataType StackTop(Stack* ps)// 获取栈顶元素
{
	assert(!StackEmpty(ps));
		return ps->array[ps->top - 1];
}

(6)获取栈中有效元素个数

int StackSize(Stack* ps)// 获取栈中有效元素个数  
{
	assert(ps);
	return ps->top;
}

(7)检测栈是否为空

int StackEmpty(Stack* ps)// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
{
	assert(ps);
	return ps->top == 0;
}

(8)销毁栈

void StackDestroy(Stack* ps)// 销毁栈 
{
	assert(ps);
	free(ps->array);
	ps->array = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

这次依然将主要的代码分成了三个源文件,Stack.c,test.c,Stack.h,其中Stack.c实现代码中的各个函数,test.c实现顺序表的相关测试,Stack.h实现用到的各种头文件与函数声明。
Stack.h

#pragma once


// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* array;
	int top;		// 栈顶/栈中的元素个数
	int capacity;  // 容量 
}Stack;

void StackInit(Stack* ps);// 初始化栈 
void StackPush(Stack* ps, STDataType data);// 入栈 
void StackPop(Stack* ps);// 出栈 

STDataType StackTop(Stack* ps);// 获取栈顶元素 
int StackSize(Stack* ps);// 获取栈中有效元素个数  
int StackEmpty(Stack* ps);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
void StackDestroy(Stack* ps);// 销毁栈 

Stack.c

#include <stdio.h>
#include "Stack.h"
#include <assert.h>
#include <malloc.h>
#include <string.h>

void StackInit(Stack* ps)// 初始化栈 
{
	assert(ps);
	ps->array = (STDataType*)malloc(sizeof(STDataType) * 10);
	if (NULL == ps->array)
	{
		assert(0);
		return;
	}
	ps->capacity = 10;
	ps->top = 0;
}

void CheckCapacity(Stack* ps)//检查容量
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		//1.开辟新空间
		STDataType* newCapacity = (STDataType*)malloc(sizeof(STDataType)*ps->top * 2);
		if (newCapacity == NULL)
		{
			assert(0);
			return;
		}
		//2.拷贝元素
		memcpy(newCapacity, ps->array, sizeof(STDataType)*ps->top);

		//3.释放旧空间
		free(ps->array);

		//4.使用新空间
		ps->array = newCapacity;
		ps->capacity *= 2;
	}
}

void StackPush(Stack* ps, STDataType data)// 入栈 
{
	assert(ps);
	CheckCapacity(ps);
	ps->array[ps->top++] = data;
}

void StackPop(Stack* ps)// 出栈 
{
	if (StackEmpty(ps))
		return;

	ps->top--;
}

STDataType StackTop(Stack* ps)// 获取栈顶元素
{
	assert(!StackEmpty(ps));
		return ps->array[ps->top - 1];
}

int StackSize(Stack* ps)// 获取栈中有效元素个数  
{
	assert(ps);
	return ps->top;
}

int StackEmpty(Stack* ps)// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
{
	assert(ps);
	return ps->top == 0;
}

void StackDestroy(Stack* ps)// 销毁栈 
{
	assert(ps);
	free(ps->array);
	ps->array = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

test.c

#include "Stack.h"

int main()
{
	Stack s;
	StackInit(&s);

	StackPush(&s, 1);
	StackPush(&s, 2);
	StackPush(&s, 3);
	StackPush(&s, 4);
	StackPush(&s, 5);
	StackPush(&s, 6);
	StackPush(&s, 7);

	printf("%d\n", StackTop(&s));
	printf("%d\n", StackSize(&s));

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值