顺序栈的基本操作(超详细)

目录

前言

一、顺序栈的定义

二、顺序栈的c++语言结构描述表示

三、顺序栈中基本操作的实现

3.1顺序栈的初始化 

3.2判断顺序栈是否为空

3.3求顺序栈的长度

3.4清空顺序栈

3.5销毁顺序栈

3.6顺序栈的入栈

3.7顺序栈的出栈

3.8求栈顶元素

3.9遍历顺序栈 

 四、顺序栈的代码实现

五、测试结果

五、总结


前言

本文参考王卓老师的数据结构视频和严蔚敏老师的《数据结构》


一、顺序栈的定义

栈:操作受限的线性表,限定仅在表尾进行插入和删除操作的线性表,即后进先出。这一端被称为栈顶,相对地,把另一端称为栈底。

顺序栈:用顺序结构存储的栈

例子:类似子弹压入弹夹,后放入的子弹可以先从弹夹弹出来。

特点:简单方便,但是容易溢出(上溢或者下溢)

二、顺序栈的c++语言结构描述表示

代码如下(示例):

typedef struct sqstack{
    int *top;//栈顶指针
    int *base;//栈底指针
    int stackSize;//栈的最大容量 
}stack;

三、顺序栈中基本操作的实现

3.1顺序栈的初始化 

数组用c++的new来动态开辟

当内存不够的时候,也即是s.base为空,则直接结束

不为空的时候,则栈的栈顶指针与栈底指针都指向同一位置

代码如下(示例):

void initStack(stack &s)
{
	s.base=new int[MaxSize];
	if(!s.base)	exit(0);//内存分配失败,结束
	s.top=s.base;//初始的时候栈的top与base相等 
	s.stackSize=MaxSize;//栈的最大容量	
} 

3.2判断顺序栈是否为空

栈顶指针与栈底指针都指向同一位置,即s.base==s.top的时候,则栈为空,返回1

否则,不为空,返回0

 代码如下(示例):

int isEmpty(stack s)
{
	if(s.base==s.top)
		return 1;//表示为空,无元素
	return 0;//不为空	
} 

3.3求顺序栈的长度

长度即为有多少个元素,可以用s.top-s.base

 代码如下(示例):

int stackLength(stack s)
{
	return s.top-s.base;
}

3.4清空顺序栈

当s.base不为空的时候,让s.top(栈顶指针)直接指向s.base(栈底),则把所有的元素逻辑上清空了

而当s.base为空的时候,则栈已经被销毁了,无需清空

 代码如下(示例):

void CleanStack(stack &s)
{
	if(s.base)
	{
		s.top=s.base;
		cout<<"成功清空"<<endl;
	}
	else
		cout<<"栈已经被销毁,无需清空"<<endl;
}

3.5销毁顺序栈

从物理层次销毁

也即是用delete将整个s.base从内存中删除

 代码如下(示例):

void DestoryStack(stack &s)
{
	if(s.base)
	{
		delete s.base;
		s.stackSize=0;
		s.base=NULL;
		s.top=NULL;
		cout<<"成功销毁"<<endl;
	}
	else
		cout<<"栈已经被销毁,无需销毁"<<endl;
}

3.6顺序栈的入栈

首先判断栈是否已经满了,如果满了则无法入栈,否则可以入栈

 代码如下(示例):

void push(stack &s,int e)
{
	if((s.top-s.base)==s.stackSize)
		cout<<"栈满了,无法添加新元素"<<endl;
	else
	{
		*(s.top)=e;
		s.top++;	
		cout<<"添加成功"<<endl;
	}	
} 

3.7顺序栈的出栈

首先判断栈是否为空,如果为空,则无法出栈,否则可以出栈 

  代码如下(示例):

void pop(stack &s,int &e)
{
	if(isEmpty(s))
	{
		cout<<"栈为空,无法弹出"<<endl;
	}	
	else
	{
		s.top--;
		e=*(s.top);
		cout<<"成功弹出"<<endl; 
	}
} 

3.8求栈顶元素

 先判断栈是否为空,为空则无法求栈顶元素,否则可以求栈顶元素

  代码如下(示例):

int top(stack s)
{
	if(isEmpty(s))
	{
		cout<<"栈为空,没有栈顶元素"<<endl;
		return -1;
	}
	else
	{
		s.top--;
		return *(s.top);
	}
}

3.9遍历顺序栈 

从栈底开始遍历 

  代码如下(示例):

void traverse(stack s)
{
	int length=stackLength(s);
	
	if(length>0)
	{
		cout<<"顺序栈的元素为:(从栈底开始遍历)"<<endl;
		for(int i=0;i<length;i++)
			cout<<s.base[i]<<" ";
	}	
	else
		cout<<"顺序栈为空"<<endl;
} 

 四、顺序栈的代码实现

#include <iostream>
using namespace std;
const int MaxSize=100;
typedef struct sqstack{
	int *top;//栈顶指针
	int *base;//栈底指针
	int stackSize;//栈的最大容量 
}stack;
void initStack(stack &s)
{
	s.base=new int[MaxSize];
	if(!s.base)	exit(0);//内存分配失败,结束
	s.top=s.base;//初始的时候栈的top与base相等 
	s.stackSize=MaxSize;//栈的最大容量	
} 
int isEmpty(stack s)
{
	if(s.base==s.top)
		return 1;//表示为空,无元素
	return 0;//不为空	
} 
int stackLength(stack s)
{
	return s.top-s.base;
}
void CleanStack(stack &s)
{
	if(s.base)
	{
		s.top=s.base;
		cout<<"成功清空"<<endl;
	}
	else
		cout<<"栈已经被销毁,无需清空"<<endl;
}
void DestoryStack(stack &s)
{
	if(s.base)
	{
		delete s.base;
		s.stackSize=0;
		s.base=NULL;
		s.top=NULL;
		cout<<"成功销毁"<<endl;
	}
	else
		cout<<"栈已经被销毁,无需销毁"<<endl;
}
//入栈
void push(stack &s,int e)
{
	if((s.top-s.base)==s.stackSize)
		cout<<"栈满了,无法添加新元素"<<endl;
	else
	{
		*(s.top)=e;
		s.top++;	
		cout<<"添加成功"<<endl;
	}	
} 
//出栈
void pop(stack &s,int &e)
{
	if(isEmpty(s))
	{
		cout<<"栈为空,无法弹出"<<endl;
	}	
	else
	{
		s.top--;
		e=*(s.top);
		cout<<"成功弹出"<<endl; 
	}
} 
int top(stack s)
{
	if(isEmpty(s))
	{
		cout<<"栈为空,没有栈顶元素"<<endl;
		return -1;
	}
	else
	{
		s.top--;
		return *(s.top);
	}
}
void traverse(stack s)
{
	int length=stackLength(s);
	
	if(length>0)
	{
		cout<<"顺序栈的元素为:(从栈底开始遍历)"<<endl;
		for(int i=0;i<length;i++)
			cout<<s.base[i]<<" ";
	}	
	else
		cout<<"顺序栈为空"<<endl;
} 
void menu()
{
	cout<<"**********************************"<<endl;
	cout<<"1.初始化"<<endl;
	cout<<"2.判断栈是否为空"<<endl;
	cout<<"3.求栈的长度"<<endl;
	cout<<"4.清空栈"<<endl;
	cout<<"5.销毁栈"<<endl;
	cout<<"6.入栈"<<endl;
	cout<<"7.出栈"<<endl;
	cout<<"8.求栈顶元素"<<endl;
	cout<<"9.遍历顺序栈"<<endl;
	cout<<"10.退出"<<endl;
	cout<<"**********************************"<<endl;
}
int main()
{
	int choice;
	stack s;
	int e1,e2;
	while(1)
	{
		menu();
		cin>>choice;
		switch(choice)
		{
			case 1:
				initStack(s);
				cout<<"初始化成功"<<endl;
				break;
			case 2:
				if(isEmpty(s))
					cout<<"栈为空"<<endl;
				else
					cout<<"栈不为空"<<endl; 
				break;
			case 3:
				cout<<"栈的长度为"<<stackLength(s)<<endl;
				break;
			case 4:
				CleanStack(s);
				break;
			case 5:
				DestoryStack(s);
				break;	
			case 6:
				cout<<"请输入想要入栈的元素值:"<<endl;
				cin>>e1;
				push(s,e1);
				break;
			case 7:
				pop(s,e2);
				cout<<"弹出的元素为"<<e2<<endl;
				break;
			case 8:
				if(top(s)!=-1)
					cout<<"栈顶元素为"<<top(s)<<endl;
				break;
			case 9:
				traverse(s);
				cout<<endl;
				break;
			case 10:
				cout<<"成功退出"<<endl;
				exit(0);
			default:
				cout<<"输入有误,请重新输入"<<endl;
				break;			
		}	
	}
} 

五、测试结果

                                          图一

                                        图二 

                                        图三

 

                                        图四 

 

                                         图五

                                         图六

                                         图七

                                          图八

                                           图九

                                            图十

                                             图十一

六、总结

        栈是一种操作受限的线性表,虽然操作受限,但是与线性表有点类似,只不过栈的插入和删除都在表尾而已。而我在本文中实现的顺序栈有点类似顺序表。我们也需要注意到顺序栈虽然实现简单,但是其容易发生溢出,在栈满的时候,还要入栈,则会上溢,而在栈空的时候,还要出栈,则会下溢,针对这个问题,我将在下一篇文章的链栈解决这个问题。

猜你喜欢

转载自blog.csdn.net/m0_53679998/article/details/125192559