基础数据结构(栈)

目录

前言:暑期复习之栈的简单理解

一·栈的设计思路

二·栈的具体代码详解

1.栈的初始化操作

2.入栈和出栈

3.取栈顶元素

4.获取栈中元素个数

5.判空判满

6.栈的增容

7.清空与销毁

三·栈的总结


前言:暑期复习之栈的简单理解

经过这两天对链表和顺序表的简单复习,接下来是对栈的基本见解。

一·栈的设计思路

       栈是一种基于先进后出(FILO)的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

       我们称数据进入到栈的动作为压栈,数据从栈中出去的动作为弹栈。栈仅限在表尾进行插入删除,表头其实也可以进行插入删除但是比较麻烦,且复杂。

逻辑图示:

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2

typedef int Status;

#define STACK_INIT_SIZE 100   //栈的初始大小
#define STACKINC 1.5      //栈的扩容倍数
typedef int SElemType;
typedef struct 
{
	SElemType* base;//栈底指针
	SElemType* top;//栈顶指针
	int stacksize; //栈的容量
}SeqStack;

二·栈的具体代码详解

栈的基本操作除了在栈顶进行插入或删除外,还有栈的初始化,判空及取栈顶元素等。

1.栈的初始化操作

利用malloc操作进行开辟空间,也就是开辟栈,并将栈结构体中的成员变量赋予一个是初始值。

Status是我们定义的一个状态变量,在结构体设计时利用宏定义。

//初始化栈
Status InitStack(SeqStack* ps)
{
	assert(ps != NULL);
	ps->base = (SElemType*)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
	if (NULL == ps->base)
	{
		return OVERFLOW;
	}
	ps->top = ps->base;
	ps->stacksize = STACK_INIT_SIZE;
	return OK;
}

2.入栈和出栈

(1)入栈:将将要入栈的数据赋值给top指针,然后top指针向后挪动一格。

//入栈
Status Push(SeqStack* ps, SElemType val)
{
	assert(ps != NULL);
	if (StackFull(ps))
	{
		return ERROR;
	}
	*ps->top = val;
	ps->top += 1;
	return OK;
}

(2)出栈:将将要出栈的数据元素赋值给pr指针,然后top指针挪动一格。

//出栈
Status Pop(SeqStack* ps, SElemType* pr)
{
	assert(ps != NULL);
	if (pr == NULL)
	{
		return NULLPTR;
	}
	if (StackEmpty(ps))
	{
		return ERROR;
	}
	ps->top -= 1;
	*pr = *ps->top;
}

3.取栈顶元素

将top指针指向的值给准备好的变量,只是想知道栈顶元素的数据值,并不是将栈顶元素取出,并删除,所以top指针不挪动。

//取栈顶元素
Status GetPop(SeqStack* ps, SElemType* pr)
{
	assert(ps != NULL);
	if (pr == NULL)
	{
		return NULLPTR;
	}
	if (StackEmpty(ps))
	{
		return ERROR;
	}
	*pr = *(ps->top - 1);
	return OK;
}

4.获取栈中元素个数

利用逻辑图示可以清楚的看到,栈顶指针-栈底指针就是栈中元素的个数


//栈中元素个数
int StackLenth(const SeqStack* ps)
{
	assert(ps != NULL);
	return(ps->top - ps->base);
}

5.判空判满

(1)判空

利用获取元素个数函数进行判空操作

//判空
bool StackEmpty(SeqStack* ps)
{
	assert(ps != NULL);
	return StackLenth(ps) == 0;
}

(2)判满

利用获取元素个数函数和栈的最大容量来进行判满

//判满
bool StackFull(SeqStack* ps)
{
	assert(ps != NULL);
	return StackLenth(ps) == ps->stacksize;
}

6.栈的增容

栈的增容:这里用到的是realloc,因为realloc可以将原来空间中的数据一个个放入新开辟的空间,并使之自动释放掉。将开辟好的newdata赋给base,然后top就是基础的栈底指针加上增容前的容量,增容成功返回true.

//增容
bool IncSize(SeqStack* ps)
{
	assert(ps != NULL);
	int total = ps->stacksize * STACKINC;
	SElemType* newdata = (SElemType*)realloc(ps->base, sizeof(SElemType) * total);
	if (NULL == newdata)
	{
		return NULLPTR;
	}
	ps->base = newdata;
	ps->top = ps->base + ps->stacksize;
	ps->stacksize = total;
	return true;
}

7.清空与销毁

(1)清空操作:

逻辑上当栈顶指针和栈底指针相同时,此栈为空栈。

//清空栈
void ClearStack(SeqStack* ps)
{
	assert(ps != NULL);
	ps->top = ps->base;
}

(2)销毁操作:

销毁栈就是释放开辟的这一片空间,并初始化其中的成员变量。

//销毁栈
void DestroyStack(SeqStack* ps)
{
	assert(ps != NULL);
	free(ps->base);
	ps->base = NULL;
	ps->top = NULL;
	ps->stacksize = 0;
}

三·栈的总结

(1)定义:栈是限定仅在表尾进行插入或删除操作的线性表。

(2)逻辑结构:与线性表相同,一对一关系,数据元素存储。

(3)物理存储结构:顺序栈和链栈

(4)运算规则:插入数据和删除数据按照后进先出的规则运算(在栈顶入栈和出栈)

(5)栈与线性表的区别:运算规则不同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值