加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

【数据结构】栈

发布时间:2020-12-15 05:54:17 所属栏目:安全 来源:网络整理
导读:1.概述 1.1 简介 栈是一种极为常用的数据结构,有两种基本操作:push和pop,这两种操作都限制在栈顶。push是从栈顶压入元素,即入栈;pop是弹出栈顶元素,即出栈。 在出栈时,要判断栈是否为空 。 可以用静态数组来模拟栈,但编译时需要指定数组的大小,即栈

1.概述


1.1 简介


栈是一种极为常用的数据结构,有两种基本操作:push和pop,这两种操作都限制在栈顶。push是从栈顶压入元素,即入栈;pop是弹出栈顶元素,即出栈。在出栈时,要判断栈是否为空


可以用静态数组来模拟栈,但编译时需要指定数组的大小,即栈的大小是固定的。还可以用类似链表的struct实现,不需要指定大小。


栈在C++的<stack>容器中全封装好了:.pop( )是出栈操作, .push( )是入栈操作, .empty( )判断栈是否为空, .top( )返回栈顶元素。


1.2 入栈出栈


描述:n个元素以1 2 ... n顺序入栈,求出栈序列有多少种。


元素的出栈情况比较复杂:可以一入栈就出栈,也可以入栈后等若干个元素入栈后再依次出栈。比如,有三个元素1、2、3,并按1 2 3的顺序入栈,其出栈序列:(1)1 2 3入栈后开始出栈,则出栈序列为3 2 1。(2)1 2入栈后开始出栈,2出栈后3入栈,此时栈中元素是3 1,出栈序列为2 3 1;也有可能2 1出栈后3入栈,则出栈序列为2 1 3。(3)……


n个元素的出栈序列的种数为C(2n,n)/(n+1),该数叫做Catalan数,具体的证明参看这里。


2. 问题


2.1 九度OJ 1108


模拟栈,根据要求输出结果。


源代码:


1108 Accepted

908KB 1083B 20MS C /?代码

#include "stdio.h"
#include "stdlib.h"

typedef struct stack
{
	int data;
	struct stack*next;
}stack;

static stack*top;

int is_empty()
{
	return top==NULL;
}

void push(int a)
{
	stack*p;
	p=(stack*)malloc(sizeof(stack));
	p->data=a;
	p->next=top;
	top=p;
}

void pop()
{
    stack*q;
	q=top;
	top=top->next;
	free(q);
}

int main()
{
	int i,m,count;
	char ch[10];
	while(~scanf("%d",&count))
	{
		top=(stack*)malloc(sizeof(stack));
		top=NULL;
		if(count>0)
		{
			for(i=count;i>=1;i--)
			{
				scanf("%s",&ch);
				if(ch[0]=='A')
				{
					if(is_empty())
						printf("En");
					else printf("%dn",top->data);	
				}
				else if(ch[0]=='P')
				{
					scanf("%d",&m);
					push(m);
				}
				else if(ch[0]=='O')
				{
					if(is_empty()) continue;
					else pop();
				}
			}
			printf("n");
		}
		else if(count==0) 
			break;
	}
	return 0;
}


2.2 POJ 1028


题目大意:有两个栈,backward和forward,BACK,FORWARD 和 VISIT命令引起两个栈的push、pop操作,输出相应的结果。


实际上,可以把backward栈的top看作是current page,接下来问题迎刃而解了。


源代码:

1028 Accepted 184K 32MS C++ 906B 2013-08-28 16:32:02

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main()
{
	string str1,str2;
	stack<string>forward;
	stack<string>backward;
	
	backward.push("http://www.acm.org/");
	
	while(cin>>str1&&str1!="QUIT")
	{
		if(str1=="BACK")
		{
			str2=backward.top();    //the top of backward stack is the current page
			backward.pop();
			if(backward.empty())
			{
				cout<<"Ignoredn";
				backward.push(str2);
			}
			else
			{
				cout<<backward.top()<<endl;
				forward.push(str2);
			}
		}
		
		else if(str1=="FORWARD")
		{
			if(forward.empty())
				cout<<"Ignoredn";
			else
			{
				cout<<forward.top()<<endl;
				backward.push(forward.top());
				forward.pop();
			}
		}
		
		else if(str1=="VISIT")
		{
			cin>>str2;
			backward.push(str2);
			while(!forward.empty())
				forward.pop();
			cout<<str2<<endl;
		}
	}
	return 0;
}

2.3 POJ 1363


题目大意:元素1,2,...,N依次入栈,输入一组序列,判定其是否为出栈序列。


思路:用poping表示输出的元素序列,

(1)push元素1,N依次入栈,在每一次push操作后,判定栈顶元素==poping[ j ];若相等,栈顶元素出栈,j++ ;

(2)push操作完成之后,若所有栈为空,则说明所有元素出栈,此序列即为出栈序列;反之,则否。


在语句while(!st.empty()&&st.top()==poping[j]&&j<n)中少加一个判定条件?!st.empty() ,一直得不到正确结果。考虑循环结束条件时,一定要周到。


源代码:


1363 Accepted 140K 63MS C++ 657B 2013-08-28 14:10:53

#include <iostream>
#include <stack>
using namespace std;

#define MAX 1000

int main()
{
	stack<int>st;
	int poping[MAX];
	int i,j,n;
	
	while(scanf("%d",&n)&&n!=0)
	{
		while(scanf("%d",&poping[0])&&poping[0]!=0)
		{
			for(i=1;i<n;i++)       //input the poping sequence
				scanf("%d",&poping[i]);
			
			while(!st.empty())     //clear the stack
				st.pop();
			
			for(i=1,j=0;i<=n;i++)
			{				
				st.push(i);
				while(!st.empty()&&st.top()==poping[j]&&j<n)
				{
					st.pop();
					j++;
				}
			}

			if(st.empty())
				printf("Yesn");
			else
				printf("Non");
		}
		printf("n");
	}
	return 0;
}

2.4 POJ 2082


题目大意在这篇文章中描述得非常清楚:有n个相邻的矩形,宽和高已知,求出能够组合形成新矩形的最大面积。


思路:用一个栈存储矩形,栈中保持矩形的高递增,cur表示刚输入的矩形,lasth表示栈顶元素的高(其实也不是,有点不好表达),curarea表示合并后的矩形的面积,maxarea表示最大矩形的面积

(1)若cur.h>=lasth,cur入栈;

(2)若cur.h<lasth,高比cur.h小的矩形出栈;在每一次出栈的过程中,进行合并操作(即合并成新矩形);由于maxarea可能出现在每一次出栈过程中,所以每一次循环都得对maxarea进行更新;

(3)置lasth=cur.h;

(4)栈可能不为空,还需要做出栈处理,操作跟(2)相类似。


源代码:

2082 Accepted 128K 125MS C++ 861B 2013-08-28 21:28:30

#include <iostream>
#include <stack>
using namespace std;

struct Rectangle
{
	int w,h;
};

stack<Rectangle>st;

int main()
{
	int i,n,lasth,totalw,curarea,maxarea;
	Rectangle cur;
	
	while(scanf("%d",&n)&&n!=-1)
	{
		lasth=0;
		maxarea=0;
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&cur.w,&cur.h);
			
			/*push stack*/
			if(cur.h>=lasth)
				st.push(cur);
			
			else
			{
				totalw=0;
				while(!st.empty()&&st.top().h>=cur.h)
				{
					totalw+=st.top().w;
					curarea=totalw*st.top().h;
					if(curarea>maxarea)
						maxarea=curarea;
					st.pop();
				}
				totalw+=cur.w;
				cur.w=totalw;
				st.push(cur);
			}
			lasth=cur.h;
		}	
		
		for(totalw=0;!st.empty();st.pop())
		{
			totalw+=st.top().w;
			curarea=totalw*st.top().h;
			if(curarea>maxarea)
				maxarea=curarea;
		}
		printf("%dn",maxarea);
	}
	return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读