See_You_In_Blog

前路浩浩荡荡,万事尽可努力。

数据结构随笔——栈,及STL中的<stack>

一、栈的定义

在我们软件应用中,栈这种后进先出数据结构的应用是非常普遍的。比如你用浏览器上网时,不管什么浏览器都有一一个“后退”键,你点击后可以按访问顺序的逆序加载浏览过的网页。这就是栈的一个实际运用。

栈(stack)是仅限在表尾进行插入和删除的线性表

二、栈的顺序存储结构及代码实现

首先来看,栈的定义,这里是用数组实现栈,实际上用链表也可以实现,称为链式栈。

个人认为栈这部分重点在于看懂源码,动手实现起来是十分容易的。

#define datatype int 
#define maxsize 1024
struct stack
{
	datatype data[maxsize];
	int top; //栈顶指针,1个元素就是0,2个就是1,以此类推
};

栈的初始化

首先要对这个结构体申请空间,然后传回该结构体的指针。

stack* init_stack() //返回类型为结构体指针的函数,初始化栈
{
	stack* s;
	s = (stack*)malloc(sizeof(stack));
	if (!s)
	{
		cout << "空间不足,申请失败" << endl;
		return NULL;
	}
	else 
	{
		s->top = -1;//定义栈底为-1
		return s;
	}
}

入栈

要判断是否为栈满,然后将该元素压入。

int push(stack* s, datatype x) //入栈
{
	if (s->top == maxsize - 1)
	{
		cout << "栈满,无法入栈" << endl;
		return 0;
	}
	else
	{
		s->data[++s->top] = x;
		return 1;
	}
}

出栈

要判断是否为空栈,然后将该元素的值传给指针。(改变函数,返回该值也可以)。

int pop(stack* s, datatype* e) //出栈一个元素,并且用e返回其值
{
	if (empty_stack(s))
	{
		cout << "栈空,无法出栈" << endl;
		return 0;
	}
	else
	{
		*e = s->data[s->top--];
		return 1;
	}
}

判断空栈

这个很简单,看top值是否为-1即可。

int empty_stack(stack* s) //判断空栈
{
	if (s->top == -1)
		return 1; //为空
	else
		return 0;
}

获得栈顶元素

datatype gettop(stack* s)
{
	if (empty_stack(s))
	{
		cout << "栈空,无栈顶元素" << endl;
		return 0;
	}
	else
		return s->data[s->top]; //返回栈顶
}

显示栈中所有元素,自上而下

void print_stack(stack* s) //显示所有元素
{
	if (empty_stack(s))
	{
		cout << "栈空,无元素" << endl;
		return;
	}
	else
	{
		for (int i = s->top; i >= 0; i--)
			cout << s->data[i] << endl;
		return;
	}
}

至于返回栈中元素数量,这个可以定义一个函数返回top+1的值,即为元素个数。同理,删除这个栈中所有元素,只需要把top的值修改为-1即可。销毁栈,释放栈空间即可。在此不多赘述。

三、STL中的<stack>

这就十分简单了,函数都封装好了。C++中stl的stack(栈)以其他容器(deque默认,vector,list)作为底层数据结构而形成,只是修改了接口以满足栈的特性。

#include<stack>//栈
stack<int>  s;//参数也是数据类型,这是栈的定义方式
s.empty()//如果栈为空返回true,否则返回false  
s.size()//返回栈中元素的个数  
s.pop()//删除栈顶元素但不返回其值  
s.top()//返回栈顶的元素,但不删除该元素  
s.push(X)//在栈顶压入新元素 ,参数X为要压入的元素

四、两栈共享空间

数组有两个端点,两个栈有两个栈底,让一个栈的栈底为0,另一个为栈的栈末端,即为数组大小的n-1处。这样,两个栈都增加元素都是往中间处靠拢。

栈1为空时,就是top1等于-1时,而当top2等于n时,即是栈2为空时,那什么时候栈满呢?

若栈2是空栈,栈1的top1等于n-1时,就是栈1满了。反之,当栈1为空栈时,top2 等于0时,为栈2满。但更多的情况,其实就是,两个指针之间相差1时,即top1 + 1 == top2 为栈满。

事实上,使用这样的数据结构,通常都是当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况。当然,这只是针对两个具有相同数据类型的栈的一一个设计上的技巧,如果是不相同数据类型的栈,这种办法不但不能更好地处理问题,反而会使问题变得更复杂。

定义

#define datatype int 
#define maxsize 1024
typedef struct
{
  datatype data[maxsize];
	int top1;
	int top2;
}doublestack;

压入元素

在压入和删除时,就只是需要判断一下对哪个栈操作而已。

int double_stack_push(doublestack* s, int stacknumber, datatype x) 
//结构体指针,要操作的栈,要压入的元素
{
	if (s->top1 + 1 == s->top2)
		return 0; //栈满
	else
	{
		if (stacknumber == 1)
			s->data[++s->top1] = x; //先自加再赋值
		else if(stacknumber==2)
			s->data[--s->top2] = x;
		return 1;
	}
}

删除元素

int double_stack_pop(doublestack* s, int stacknumber,datatype* e)
{
	if (stacknumber == 1)
	{
		if (s->top1 == -1)
			return 0; //栈1为空
		else
			*e = s->data[s->top1--];//先出栈再自减
	}
	else if (stacknumber == 2)
	{
		if (s->top1 == maxsize)
			return 0; //栈1为空
		else
			*e = s->data[s->top2++];//先出栈再自加
	}
	return 1;
}
posted @ 2020-04-06 14:12  爱打代码的喵  阅读(419)  评论(0)    收藏  举报