简单的数据结构:栈

1.栈的基本概念

1.1栈的定义

栈是一种线性表,只能在一端进行数据的插入或删除,可以用数组链表来实现,这里以数组为例进行说明

栈顶 :数据出入的那一端,通常用Top表示

栈底 :相对于栈顶的另一端,也是固定的一端,不允许数据的插入和删除

空栈:不含数据的栈

1.2栈的基本操作

栈的初始化:通常用STInit(&St)表示,用来初始化一个栈St

入栈:一般用STPush(&St, x)表示,给栈St插入数据x,也叫做进栈压栈,同时要注意是否栈满,栈满则需要扩容

出栈:一般用STPop(&St)表示,给栈St删除数据,有时也叫弹栈,需要注意是否栈空

 判断栈空:用STEmpty(&St)表示,常用到判断栈空,因此封装成函数,方便使用,返回值一般用bool类型,true表示栈空,false表示栈非空 

 读栈顶元素:用STTop(&St)表示,栈非空则返回栈顶元素

获取数据个数:用STSize(&St)表示 ,返回数据个数

2.栈的实现 

用一个结构体描述这个栈的各项数据:

typedef int STDataType;

typedef struct Stack
{
    STDataType* a;   //栈底
    int top;                 //栈顶
    int capacity;         //栈容量
}ST;

初始化栈: 

void STInit(ST* pst)
{
    assert(pst);
    pst->a = NULL;
    //top指向栈顶数据的下一个位置
    pst->top = 0;
    pst->capacity = 0;
}

top可以指向栈顶,也可以指向栈顶的下一个位置,top的指向会影响后续的数据插入、删除、销毁,以及判空 

 栈的销毁:

void STDestroy(ST* pst)
{
    assert(pst);

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

 入栈:

void STPush(ST* pst, STDataType x)
{
    assert(pst);

    //扩容
    if (pst->top == pst->capacity)
    {
        int    newcapacity = pst->capacity == 0 ? 4 : pst->capacity* 2; //空栈则让栈空间为4
        STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
        if (tmp == NULL)
        {
            perror("realloc fail");    
            return;
        }

        pst->a = tmp;
        pst->capacity = newcapacity;
    }
    pst->a[pst->top] = x;
    pst->top++;
}
 

利用realloc的特性,空栈则执行malloc的功能 

出栈:

void STPop(ST* pst)
{
    assert(pst);
    assert(pst->top > 0);   //防止栈空
    pst->top--;
}

 取栈顶数据:

STDataType STTop(ST* pst)
{
    assert(pst);
    return pst->a[pst->top - 1];  //返回值为STDataType
}

判空:

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

获取栈的数据个数:

int    STSize(ST* pst)
{
    assert(pst);
    return pst->top;

3.所有代码 

以数组为例实现栈,分为头文件(Stack.h)和函数实现(Stack.c)以及测试(test.c)

Stack.h:

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

typedef int STDataType;

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

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

//入栈 出栈
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);

//取栈顶数据
STDataType STTop(ST* pst);

//判空
bool STEmpty(ST* pst);

//获取数据个数
int	STSize(ST* pst);

Stack.c:

#include"Stack.h"

//初始化栈
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置
	pst->top = 0;
	pst->capacity = 0;
}
void STDestroy(ST* pst)
{
	assert(pst);

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

//入栈 出栈
void STPush(ST* pst, STDataType x)
{
	assert(pst);

	//扩容
	if (pst->top == pst->capacity)
	{
		int	newcapacity = pst->capacity == 0 ? 4 : pst->capacity* 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");	
			return;
		}

		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}

//取栈顶数据
STDataType STTop(ST* pst)
{
	assert(pst);
	return pst->a[pst->top - 1];
}

//判空
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;
}

//获取数据个数
int	STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

test.c

#include"Stack.h"
int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);
	while (!STEmpty(&s))
	{
		printf("%d\n", STTop(&s));
		STPop(&s);
	}
	STDestroy(&s);
	return 0;
}

 

  • 100
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 96
    评论
评论 96
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值