TD03-栈


一、栈的基本概念

1、首先栈是一种线性表,但这种线性表只能在一端进行插入和删除
2、后进先出(Last In First Out)

二、顺序栈

顺序栈:采用顺序存储的栈。它利用一组连续的存储单元存储元素,还有top指针指向栈顶元素

1.储类型描述

栈的顺序存储类型描述:

#define MaxSize 50
#define Elemtype int
//栈的顺序存储类型
typedef struct {
	Elemtype data[MaxSize];
	int top;
}SqStack;

栈顶指针:s.top, 初始设置s.top=-1
栈顶元素:s.data[s.top]
栈空条件:s.top==-1
栈满条件:s.top= =MaxSize-1(top指针指向栈顶元素
栈长:s.top+1

带栈顶和栈底指针的存储类型:

//带栈顶和栈底指针的存储类型
typedef struct {
	Elemtype* base;
	Elemtype* top;		//这里的top指向栈顶元素的下一个位置
	int stacksize;
}SqStack2;

带栈顶和栈底指针的 栈满条件:S.top - S.base = = S.stacksize(top指向栈顶元素的下一个位置)

2.基本操作

1、初始化

//初始化
void InitStack(SqStack& s) {
	s.top = -1;
}

//带栈底指针的初始化
Status InitStack2(SqStack2& s) {
	s.base = new Elemtype[MaxSize];
	if (!s.base)
		return false;
	s.top = s.base;
	s.stacksize = MaxSize;
	return true;
}

2、判栈空

//栈判空
bool StackEmpty(SqStack s) {
	if (s.top == -1)
		return true;
	else
		return false;
}

//带栈底指针的判空
bool StackEmpty2(SqStack2 s) {
	if (s.top == s.base)
		return true;
	else
		return false;
}

3、进栈

//进栈
bool Push(SqStack& s, Elemtype x) {
	if (s.top == MaxSize - 1)		//判断是否满栈;因为data[MaxSize]数组下标从0开始
		return false;
	s.data[++s.top] = x;			//将元素压入栈顶,栈顶指针加一
	return true;
}

//带栈底指针的进栈
int Push(SqStack& S, ElemType e)
{
	if (S.top - S.base == S.stacksize)
		return FALSE;
	*S.top = e;				//元素压入栈顶
	S.top++;				//栈顶指针加一
	return OK;
}

4、出栈

//出栈
bool Pop(SqStack& s, Elemtype& x) {
	if (s.top == -1)				//判断是否栈空
		return false;
	x = s.data[s.top--];			//将元素赋值给x,栈顶指针减一
	return true;
}

//带栈底指针的出栈
int Pop(SqStack& S, ElemType& e)
{
	if (S.top == S.base)			//if(StackEmpty(S))
		return ERROR;
	--S.top;						//栈顶指针减一
	e = *S.top;						//栈顶元素赋值给e;	两步合起来*S.top++=e
	return OK;
}

5、读栈顶元素

//读栈顶元素
bool GetTop(SqStack& s, Elemtype& x) {
	if (s.top == -1)				//判断是否栈空
		return false;
	x = s.data[s.top];				//返回栈顶元素,栈顶指针值不变
	return true;
}

6、带栈底指针求栈长度

//带栈底指针求栈长度
int StackLength(SqStack2 s) {
	return s.top - s.base;
}

7、带栈底指针清空栈

//带栈底指针清空栈
bool ClearStack(SqStack2 s) {
	if (s.base)
		s.top = s.base;
	return true;
}

8、带栈底指针销毁栈

//带栈底指针销毁栈
bool DestoryStack(SqStack2 s) {
	if (s.base) {
		delete s.base;				//delete:是释放用户开辟的空间,把数组回归内存
		s.stacksize=0;
		s.base = s.top = NULL;		//置NULL是防止野指针的生成,野指针:访问一个已销毁或者访问受限的内存区域的指针
	}
	return true;
}

注:
栈顶指针初始化s.top=-1
进栈 :s.data[++s.top] = x;
出栈:x = s.data[s.top–];

栈顶指针初始化s.top=0
进栈 :s.data[s.top++] = x;
出栈:x = s.data[–s.top];

(主要是思想,算法的逻辑关系为主体。)

三、共享栈

1、利用栈底位置相对不变特性,可以让两个顺序栈共享一个一维数组空间

2、两个栈的栈顶指针都指向栈顶元素
判断栈空:
top0=-1时0号栈为空,
top1=MaxSize时1号栈为空

3、当且仅当两个栈顶指针相邻时
判断栈满:
top1-top0=1

4、0号栈进栈时top0先加一再赋值;1号栈进栈时top1先减一再赋值;
出栈相反

四、链栈

1、采用链式存储的栈称为链栈
2、优点:便于多个栈共享存储空间和提高效率
3、采用链式存储,便于结点的插入和删除
3、通常使用单链表实现,并操作在单链表的表头进行
4、这里链栈没有头结点,Lhead指向栈顶元素

1.储类型描述

栈的链式存储类型:

//链式存储类型描述
typedef struct Linknode {
	Elemtype data;					//数据域
	struct Linknode* next;			//指针域	用了嵌套定义
}StackNode, * LiStack;

1、链表的头指针就是栈顶(参考头插法理解)
2、不需要头结点
3、基本不存在栈满的情况
4、空栈相当于头指针指向空
5、插入和删除仅在栈顶执行

2.基本操作

链栈初始化:

//链栈初始化
bool InitStack(LinkStack& s) {
	s = NULL;						//构造一个空栈s,栈顶指针置空
	return true;
}

判断链栈是否为空:

//判断链栈是否为空
bool StackEmpty(LinkStack s) {
	if (s == NULL)
		return true;
	else
		return false;
}

链栈入栈:

//链栈入栈
bool Push(LinkStack& s, Elemtype e) {
	StackNode* p = (StackNode*)malloc(sizeof(StackNode));
	p->data = e;						//赋值
	p->next = s;						//插入栈顶
	s = p;								//修改栈顶指针
	return true;
}

链栈出栈:

//链栈出栈
bool Pop(LinkStack& s, Elemtype& e) {
	if (s==NULL)						//栈空
		return false;
	e = s->data;						//赋值
	StackNode* p = (StackNode*)malloc(sizeof(StackNode));
	p = s;								//用p临时保存栈顶元素空间,以备释放
	s = s->next;						//修改栈顶指针
	delete p;							//释放栈顶元素的空间
	return true;
}

取栈顶元素:

//取栈顶元素
Elemtype GetTop(LinkStack s) {
	if (s != NULL)					//栈非空
		return s->data;				//取元素
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值