【数据结构】C++实现之栈结构

1、概念
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶(top),相对地,把另一端称为栈底(bottom)。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。【LIFO】“last in first out” 后进先出
【两种:顺序结构栈、链式结构栈】

2、栈的特点
1)栈是线性表,一种特殊线性表。特殊在于插入,删除位置
2)栈的插入操作:又称进栈,入栈等
3)栈的删除操作:又称出栈、弹栈等
在这里插入图片描述
4)Question:最先进栈的元素是不是只能最后出栈?
**答案:**肯定是不对的,因为栈只是对线性表的插入,删除操作位置进行限定,但是没有在时间上做出要求。如下所示,一种5种,这里只写了三种。
在这里插入图片描述
3、栈的抽象数据结构
1)常用操作

InitStack(*S);	//初始化操作,建立一个空栈
DestroyStack(*S);	//若栈存在,则销毁它
ClearStack(*S);		//清空栈
StackEmpty(S);		//判断栈是不是空的,true or flase
GetTop(S,*e);		//若栈存在且非空,返回顶端元素
Push(*S,e);			//若栈存在,则插入元素e,且使其成为顶端元素
Pop(*S,*e);			//删除顶端元素,以e返回
StackLength(S);		//返回栈中元素个数

4、栈的顺序存储结构
在这里插入图片描述
4.1)栈的结构代码

typedef int SElemType;
typedef int Status;

struct sqstack{
		SElemType data[MAXSIZE];
		int top;				//用于栈顶指针
	};

4.2)栈的初始化

void STACK::InitStack(sqstack *s)     //初始化顺序栈
{
	s->top = -1;
	for (int i = 0; i < MAXSIZE - 1; i++)
		s->data[i] = 0;
}

4.3)栈的插入
在这里插入图片描述

STACK::Status STACK::Push(sqstack *s, SElemType e)
{
	if (s->top == MAXSIZE - 1)  //若栈已经满了,抛出异常
		return ERROR;
	s->top++;
	s->data[s->top] = e;
	return OK;
}

4.4)栈的删除

STACK::Status STACK::Pop(sqstack *s, SElemType *e)
{
	if (s->top == -1)      //判断是不是空栈
		return ERROR;
	*e = s->data[s->top];
	s->top--;
	return OK;
}

4.5、两顺序结构栈空间共享
https://blog.csdn.net/weixin_43340991/article/details/86375829
在这里插入图片描述

//两栈(相同类型)栈空间共享
struct sqdoublestack{
	SElemType data[MAXSIZE];
	int top1;	//用于栈1顶指针
	int top2;	//用于栈2顶指针
};
STACK::Status STACK::Push_Double(sqdoublestack *s, SElemType e, int stacknumber)
{
	if (s->top1 + 1 == s->top2)  //栈满
		return ERROR;


	if (stacknumber == 1)  //表示栈1有元素进入
		s->data[++s->top1] = e;
	else if (stacknumber == 1)
		s->data[--s->top2] = e;
	return OK;
}

STACK::Status STACK::Pop_Double(sqdoublestack *s, SElemType *e, int stacknumber)
{
	if (stacknumber == 1)  //表示栈1有元素进入
	{
		if (s->top1 == -1)
			return ERROR;
		*e = s->data[s->top1--];
	}

	else if (stacknumber == 2)  //表示栈1有元素进入
	{
		if (s->top1 == MAXSIZE)
			return ERROR;
		*e = s->data[s->top2++];
	}
	return OK;
}

5、链式存储结构栈

//栈的链式存储结构
struct stacknode{
	SElemType data;
	stacknode *next;
	};
typedef stacknode *StackNodeptr; //定义指向结构体stacknode类型的指针

/*链式结构栈数据结构*/
struct LinkStack{
	StackNodeptr top;
	int count;
	};

在这里插入图片描述

5.1 链式结构初始化

//栈的新元素插入操作
void LinkSTACK::InitStack(LinkStack *s)
{
	s->top = NULL;
	s->count = 0;
}

5.2 链式结构进栈操作
在这里插入图片描述

LinkSTACK::Status LinkSTACK::Push(LinkStack *s, SElemType e)
{
	StackNodeptr p = new stacknode; //产生新节点
	p->data = e;            //新节点赋值数据
	p->next = s->top;      //新节点更新指针域
	s->top = p;
	s->count++;
	return OK;
}

5.3 链式结构栈删除操作
在这里插入图片描述

LinkSTACK::Status LinkSTACK::Push(LinkStack *s, SElemType e)
{
	StackNodeptr p = new stacknode; //产生新节点
	p->data = e;            //新节点赋值数据
	p->next = s->top;      //新节点更新指针域
	s->top = p;
	s->count++;
	return OK;
}

6 链式与顺序存储结构栈完整代码
1)stack.h

#pragma once
namespace STACK{

#define MAXSIZE 10
typedef int SElemType;
typedef int Status;

struct sqstack{
		SElemType data[MAXSIZE];
		int top;				//用于栈顶指针
	};


//两栈(相同类型)栈空间共享
struct sqdoublestack{
	SElemType data[MAXSIZE];
	int top1;	//用于栈1顶指针
	int top2;	//用于栈2顶指针
};

void InitStack(sqstack *);
Status Push(sqstack *, SElemType);
Status Pop(sqstack *, SElemType *);
Status StackLength(sqstack);
Status Push_Double(sqdoublestack *, SElemType, int);
Status Pop_Double(sqdoublestack *, SElemType *, int);
}

namespace LinkSTACK{

#define MAXSIZE 10
#define ERROR 0
#define OK 1

typedef int SElemType;
typedef int Status;

//栈的链式存储结构
struct stacknode{
	SElemType data;
	stacknode *next;
	};
typedef stacknode *StackNodeptr; //定义指向结构体stacknode类型的指针

/*链式结构栈数据结构*/
struct LinkStack{
	StackNodeptr top;
	int count;
	};
void InitStack(LinkStack *);
Status Push(LinkStack *, SElemType);
Status StackEmpty(LinkStack);
Status Pop(LinkStack *, SElemType *);
}

2)顺序存储栈代码stack.cpp

#include"iostream"
#include"stack.h"
using namespace std;
/*
InitStack(*S);	//初始化操作,建立一个空栈
DestroyStack(*S);	//若栈存在,则销毁它
ClearStack(*S);		//清空栈
StackEmpty(S);		//判断栈是不是空的,true or flase
GetTop(S,*e);		//若栈存在且非空,返回顶端元素
Push(*S,e);			//若栈存在,则插入元素e,且使其成为顶端元素
Pop(*S,*e);			//删除顶端元素,以e返回
StackLength(S);		//返回栈中元素个数
*/


//栈的顺序存储结构
#define ERROR 0
#define OK 1

void STACK::InitStack(sqstack *s)     //初始化顺序栈
{
	s->top = -1;
	for (int i = 0; i < MAXSIZE - 1; i++)
		s->data[i] = 0;
}

STACK::Status STACK::Push(sqstack *s, SElemType e)
{
	if (s->top == MAXSIZE - 1)  //若栈已经满了,抛出异常
		return ERROR;
	s->top++;
	s->data[s->top] = e;
	return OK;
}

STACK::Status STACK::Pop(sqstack *s, SElemType *e)
{
	if (s->top == -1)      //判断是不是空栈
		return ERROR;
	*e = s->data[s->top];
	s->top--;
	return OK;
}

STACK::Status STACK::StackLength(sqstack s)
{
	if (s.top == -1)
		return 0;
	return s.top + 1;
}

STACK::Status STACK::Push_Double(sqdoublestack *s, SElemType e, int stacknumber)
{
	if (s->top1 + 1 == s->top2)  //栈满
		return ERROR;


	if (stacknumber == 1)  //表示栈1有元素进入
		s->data[++s->top1] = e;
	else if (stacknumber == 1)
		s->data[--s->top2] = e;
	return OK;
}

STACK::Status STACK::Pop_Double(sqdoublestack *s, SElemType *e, int stacknumber)
{
	if (stacknumber == 1)  //表示栈1有元素进入
	{
		if (s->top1 == -1)
			return ERROR;
		*e = s->data[s->top1--];
	}

	else if (stacknumber == 2)  //表示栈1有元素进入
	{
		if (s->top1 == MAXSIZE)
			return ERROR;
		*e = s->data[s->top2++];
	}
	return OK;
}

3)链式存储结构栈代码LinkStack.cpp

#include"iostream"
#include"stack.h"
using namespace std;
/*
InitStack(*S);	//初始化操作,建立一个空栈
DestroyStack(*S);	//若栈存在,则销毁它
ClearStack(*S);		//清空栈
StackEmpty(S);		//判断栈是不是空的,true or flase
GetTop(S,*e);		//若栈存在且非空,返回顶端元素
Push(*S,e);			//若栈存在,则插入元素e,且使其成为顶端元素
Pop(*S,*e);			//删除顶端元素,以e返回
StackLength(S);		//返回栈中元素个数
*/

//栈的新元素插入操作
void LinkSTACK::InitStack(LinkStack *s)
{
	s->top = NULL;
	s->count = 0;
}


LinkSTACK::Status LinkSTACK::Push(LinkStack *s, SElemType e)
{
	StackNodeptr p = new stacknode; //产生新节点
	p->data = e;            //新节点赋值数据
	p->next = s->top;      //新节点更新指针域
	s->top = p;
	s->count++;
	return OK;
}

LinkSTACK::Status LinkSTACK::StackEmpty(LinkStack s)
{
	if (s.top == NULL)
		return true;
	return false;
}

LinkSTACK::Status LinkSTACK::Pop(LinkStack *s, SElemType *e)
{
	StackNodeptr p ; //产生新节点
	if (StackEmpty(*s))   //栈为空时
		return ERROR;
	*e = s->top->data;
	p = s->top;          //将删除的数据地址赋给指针p
	s->top = p->next;
	delete p;
	s->count--;
	return OK;

}
发布了30 篇原创文章 · 获赞 6 · 访问量 5690

猜你喜欢

转载自blog.csdn.net/qq_32643313/article/details/105357024