栈——C语言实现

栈的定义:栈是一种先进后出的数据结构,即先入栈的最后出栈。
在这里插入图片描述

因此,对于一个顺序存储结构栈,只允许头添加,尾删除。
链式结构的栈的本质就是限制了操作的链表,那么为什么有了链表还要有栈呢,这其实有些工作场合来决定的,而栈的使用则可以很好地提高工作效率。
如果想了解链表的相关知识,请参见:链表的插入操作
栈的实际应用:

  1. 括号匹配问题

【算法思想】

在检验算法中设置一个栈。若读入的是左括号,则直接入栈,等待相匹配的同类右括号;若读入的是右括号,且与当前栈顶的左括号同类型,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况。另外,如果输入序列已读尽,而栈中仍有等待匹配的左括号,或者读入了一个右括号,而栈中已无等待匹配的左括号,均属不合法的情况。当输入序列和栈同时变为空时,说明所有括号完全匹配。
2. 表达式求值

【算法思想】
(1)规定优先级表;
(2)设置两个栈:OVS(运算数栈)和OPTR(运算符栈);
(3)自左向右扫描,遇操作符则与OPTR栈顶优先级比较:

当前操作符 > OPTR栈顶,则进OPTR栈;当前操作符 ≤ OPTR栈顶,OVS栈顶、次顶和OPTR栈顶,退栈形成运算T(i), T(i)进OVS栈。

第一列为栈顶运算符,第一行为当前操作符。
算数四则运算的规则是1)先乘除,后加减;2)从左算到右;3)先括号内后括号外。 由此,算式4+23-10/5的计算顺序为4+23-10/5=4+6-10/5=4+6-2=8。 给定一个以“#”作为结束符的算式,求出算式的结果。

栈的问题还有很多,这里就不一一列举

下面栈的实现代码如下:

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

typedef int bool;
#define true  1
#define false 0

typedef struct Data
{
	int nValve;
	struct Data *pNext;
}Data;

typedef struct Stack
{
	Data *pTop;
	int nCount;
}Stack;

void PushStack(Stack *pTop,int elem);
int PopStack(Stack *pTop);
void Init(Stack **pTop);
void Clear(Stack *pStack);
Data *GetTop(Stack *pStack);
void Destroy(Stack **pStack);
int GetCount(Stack *pStack);
bool IsEmpty(Stack *pStack);

int main()
{
	Stack *pStack = NULL;
	//初始化栈指针
	Init(&pStack);
//	Destroy(&pStack);
	PushStack(pStack,1);
	PushStack(pStack,2);
	PushStack(pStack,3);
	PushStack(pStack,4);
	PushStack(pStack,5);

	printf("栈顶元素为%d\n",GetCount(pStack));
	printf("%d\n",PopStack(pStack));

	//Data *p = GetTop(pStack);
	printf("GetCount = %d\n",GetCount(pStack));
	//printf("GetTop = %d\n",p->nValve);
	Clear(pStack);
	if(IsEmpty(pStack) == true)
	{
		printf("栈为空\n");
	}
	else
		printf("栈不为空\n");

	printf("栈顶元素为%d\n",GetCount(pStack));
	printf("%d\n",PopStack(pStack));

	printf("栈顶元素为%d\n",GetCount(pStack));
	printf("%d\n",PopStack(pStack));

	printf("栈顶元素为%d\n",GetCount(pStack));
	printf("%d\n",PopStack(pStack));

	printf("栈顶元素为%d\n",GetCount(pStack));
	printf("%d\n",PopStack(pStack));

	return 0;
}

void Init(Stack **pStack)
{
	//为栈顶指针申请空间
	*pStack = (Stack*)malloc(sizeof(Stack));
	(*pStack)->pTop = NULL;
	(*pStack)->nCount = 0;
}
void PushStack(Stack *pStack,int elem)
{
	//判断栈是否存在
	if(pStack == NULL) exit(1);

	//来一个元素,申请一块空间添加
	Data *pNode = (Data*)malloc(sizeof(Data));
	pNode->nValve = elem;
	pNode->pNext = pStack->pTop;
	pStack->pTop = pNode;
	pStack->nCount++;
}

int PopStack(Stack *pStack)
{
	//判断栈是否存在
	if(pStack == NULL) exit(1);

	//如果栈为空
	if(pStack->pTop == NULL) return -1;
	//删除栈顶元素并返回值
	int elem = pStack->pTop->nValve;
	Data *pDel = pStack->pTop;
	pStack->pTop = pStack->pTop->pNext;
	free(pDel);
	pDel = NULL;
	pStack->nCount--;

	return elem;
}

void Clear(Stack *pStack)
{
	//判断栈是否存在
	if(pStack == NULL) exit(1);

	while(pStack->pTop != NULL)
	{
		PopStack(pStack);
	}
}

void Destroy(Stack **pStack)
{
	//判断栈是否存在
	if(*pStack == NULL) exit(1);

	Clear(*pStack);
	free(*pStack);
	*pStack = NULL;
}

Data *GetTop(Stack *pStack)
{
	//判断栈是否存在
	if(pStack == NULL) exit(1);

	return pStack->pTop;
}

int GetCount(Stack *pStack)
{
	//判断栈是否存在
	if(pStack == NULL) exit(1);

	return pStack->nCount;
}

bool IsEmpty(Stack *pStack)
{
	//判断栈是否存在
	if(pStack == NULL) exit(1);

	if(pStack->pTop == NULL)
		return true;
	else
		return false;
}

上面就是栈的实现代码,如有错误,欢迎指正!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bug.Remove()

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

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

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

打赏作者

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

抵扣说明:

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

余额充值