c语言实现栈

一.栈

1.栈(Stack):只允许在一端进行插入或者删除的线性表

3a00438075a9408f9324db6bc5ef356f.png

 栈顶:允许线性表的插入和删除的一端

栈底:不允许插入和删除的那一端

栈又称为后进先出(Last First Out)的线性表简称LIFO

 

这里阐明一点访问栈里的元素就代表着栈的销毁,当栈里的元素出栈时才能访问到该元素

2.c语言实现栈

typedef int StackDataType;
typedef struct Stack
{
	StackDataType* a;   //动态内存
	int top;            //栈顶
	int capacity;       //栈的容量
}ST;

//接口
void StackInit(ST* st);        //初始化栈
void StackDestory(ST* st);     //销毁栈
void StackPush(ST* st, StackDataType x);   //入栈
void StackPop(ST* st);         //出栈
bool StackEmpty(ST* st);       //查看栈是否为空
StackDataType StackTop(ST* st);//查看栈顶元素
int StackSize(ST* st);         //栈中元素的个数

1.初始化栈

栈是动态开辟的空间只需要将数组的指针置为空即可,栈顶置为0,容量置为0

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

2.栈的销毁

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

3.入栈

入栈需要保证栈有容量,所以检查完指针不为空后就需要检查栈的容量,当栈顶位置与栈的容量相等时就需要扩容 ,因为在栈初始化后第一次有元素入栈时,栈的容量就给4个大小的空间,以后入栈时容量满了就在原来的基础上扩大两倍的容量(两倍比较合适)扩容完成后需要判断是否成功,没有成功扩容就没必要进行继续的操作exit(-1)直接退出程序并且报错。扩容成功后在栈顶插入元素x ,top++。

void StackPush(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, newCapacity*sizeof(STDataType));//扩容
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}

	ps->a[ps->top] = x;   //在栈顶压入x
	ps->top++;    //压入栈一个元素,栈顶就移动一位
}

4.出栈

出栈必须保证栈里面有元素,所以要要调用StackEmpt 函数,元素出栈后top--.

void StackPop(ST* st)  //出栈
{
	assert(st);
	assert(!StackEmpty(st));
	
	st->top--;

}

5.访问栈顶元素

函数的返回类型是栈存储的元素类型,首先检查指针的有效性,访问元素得保证栈得有元素

调用StackEmpty 函数,之前top初始化为0,指向的是第一个元素的位置,每插入一个元素top就往后移动一次,栈顶元素的位置就在top的前一个,栈顶元素在st->top-1的位置

StackDataType StackTop(ST* st)
{
	   assert(st); 
		assert(!StackEmpty(st));

		return st->a[st->top - 1];


}

6.判断栈是否为空

如果栈为空,那top就为0 ,式子st->top==0 成立bool函数的返回值就为1

反之,栈不为空返回bool函数就返回0

bool StackEmpty(ST* st)
{
	return st->top == 0;
}

7.查看栈的元素个数

栈的元素个数就是栈顶的位置

int StackSize(ST* st)
{
	return st->top;
}

整体代码:

Stack.h

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

typedef int StackDataType;

typedef struct Stack
{
	//数组,容量,栈顶
	StackDataType* a;
	int top;
	int capacity;
}ST;


void StackInit(ST* st);
void StackDestory(ST* st);


void StackPush(ST* st, StackDataType x);
void StackPop(ST* st);
StackDataType StackTop(ST* st);

bool StackEmpty(ST* st);
int StackSize(ST* st);

Stack.c:

#include"Stack.h"


void StackInit(ST* st)
{

	st->a = NULL;
	st->capacity = st->top = 0;

}
void StackDestory(ST* st)
{

	free(st->a);
	st->a = NULL;
	st->capacity = st->top = 0;

}


void StackPush(ST* st, StackDataType x)  //入栈
{
	assert(st);
	//检查容量
	if (st->capacity == st->top)
	{
		int newcapacity = st->capacity ==0? 4 : st->capacity * 2;
		StackDataType* tmp = (StackDataType*)realloc(st->a, newcapacity * sizeof(StackDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!!!");
			exit(-1);
		}
		//成功申请空间
		st->capacity = newcapacity;
		st->a = tmp;
	}

	st->a[st->top] = x;
	st->top++;
	


}




void StackPop(ST* st)  //出栈
{
	assert(st);
	assert(!StackEmpty(st));
	
	st->top--;




}




StackDataType StackTop(ST* st)
{
	   assert(st); 
		assert(!StackEmpty(st));

		return st->a[st->top - 1];


}

bool StackEmpty(ST* st)
{
	return st->top == 0;
}
int StackSize(ST* st)
{
	return st->top;
}

test.c:

#include"Stack.h"


void TestStack()
{
	ST st;

	StackInit(&st);
	StackPush(&st, 5);
	StackPush(&st, 4);
	StackPush(&st, 3);
	StackPush(&st, 2);
	StackPush(&st, 1);
	while (!StackEmpty(&st))
	{

		printf("%d", StackTop(&st));
		StackPop(&st);
		printf("\n");

	}




	StackDestory(&st);

}

int main()
{
	TestStack();



	return 0;
}

 

 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bite-ccc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值