数据结构——栈(C语言)

1. 栈的定义

       在学习写栈之前,我们需要了解一下栈是什么。所谓栈,就是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作,进行数据插入和删除的一端称为栈顶,另一端称为栈底,栈中的数据遵循后进先出的原则。图示如下:

       栈的实现一般可以通过数组和链表实现,相对来说数组更优,因为栈不涉及在数据中间的插入和删除,仅在栈顶实现插入和删除,相比之下数组所需代价更小。因此本章我们也采用数组的方法实现栈。

2. 代码实现

2.1 实现准备

typedef int STDataType;//为了方便后序对数据类型进行更改
typedef struct Stack//定义栈
{
	STDataType* a;//使用数组存储
	int top;      //表示栈顶
	int capacity; //表示栈的大小
}ST;

2.2 栈的初始化

        在栈的初始化中,我们将创建的栈中的数组首地址置为NULL,将栈顶top栈能储存的元素个数capacity初始化为0。也可将top初始化为-1,在后续插入删除等操作中要注意变更top的使用方式,此处采用初始化为0。

void STInit(ST* ps)
{
	assert(ps);//防止初始化前创建失败等情况发生
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

2.3 栈的销毁

void STDestroy(ST* ps)
{
	assert(ps);//防止栈已经为空
	free(ps->a);//释放开创的数组中的内存
	ps->a = NULL;//置空
	ps->top = ps->capacity = 0;//置0
}

2.4 插入数据

        在插入数据前,我们需要进行判断栈是否已满,若未满,则插入元素,top加1,若满了则用realloc开辟更多的空间,每次扩展为原空间大小的2倍,若capacity为0,则先给一个新空间大小(此处给的4),再进行空间开辟。空间足够后,将重新开辟的空间tmp给ps(栈)中的a(数组),将新的空间大小newCapaciity赋值给capacity,最后再进行插入元素操作。

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)//判断栈是否已经满了
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//新空间大小
        //开辟空间
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (NULL == tmp)//判断是否开辟成功
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;//插入元素
	ps->top++;
}

 2.5 删除数据

        该操作很简单,只需要将top减去1,这样我们就再找不到该数据。

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);//若top<=0,无意义

	ps->top--;
}

 2.6 记录栈内数据个数

        top即为栈内数据的个数,若top初始化为的-1,则栈内数据的个数等于top+1。

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

2.7 判断栈内是否无数据

        当top等于0时则说明栈内无数据,若top初始化为的-1,则top等于-1时则说明栈内无数据。

bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

2.8 取栈顶元素

        top-1则为栈顶元素下标。

STDataType STGetTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];//返回栈顶元素
}

3. 完整代码

3.1 Stack.h

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

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void STInit(ST* ps);//初始化栈

void STDestroy(ST* ps);//销毁栈

void STPush(ST* ps, STDataType x);//放入元素

void STPop(ST* ps);//消除栈顶元素

int STSize(ST* ps);//获取栈内元素个数

bool STEmpty(ST* ps);//判断栈是否为空

STDataType STGetTop(ST* ps);//获取栈顶元素

3.2 Stack.c

#include "Stack.h"
void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (NULL == tmp)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	ps->top--;
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

STDataType STGetTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];//返回栈顶元素
}

3.3 test.c (测试)

#include "Stack.h"
void test1()
{
	ST st;
	STInit(&st);//初始化
    //插入数据
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
    //此处栈已满,可以测试出扩展空间是否成功
	STPush(&st, 5);
	printf("%d\n", STSize(&st));//打印栈内元素数量
	STPop(&st);//删除栈顶元素
	printf("%d\n", STSize(&st));//打印栈内元素数量
	while (!STEmpty(&st))//打印栈内元素
	{
		printf("%d ", STGetTop(&st));
		STPop(&st);
	}
	printf("\n");
	STDestroy(&st);//销毁栈
}
int main()//主函数
{
	test1();
	return 0;
}

        本次内容就到这里啦,欢迎大家提出问题和建议!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值