算法入门经典之栈和队列篇
2016-07-17 01:55
357 查看
做对的事情比把事情做对重要
最近一段时间会对数据结构的知识和算法基础进行总结,尽量一天一更!如果时间错不开的话,第二天会补上。
数据结构中,栈和队列是最基础的也是简单的,一种是先进后出的线性数据结构,另外一种是先进先出的线性数据结构!
样例输入:7
样例输出:1 3 5 7 4 2 6
分析:先开始是扔掉1,然后把2排到最后,然后扔掉3,把4排到最后······,我们会很自然的想到队列,就像排队一样,银行柜台前,第一个人先排的队,然后第一个人办完事之后第一个走······
运行结果:
![](https://img-blog.csdn.net/20160717004337442)
单看这个程序的输出结果,没有任何错误,答案就是我们想要的,现在让我们看看rear的值到最后是多大?
![](https://img-blog.csdn.net/20160717004731632)
rear 的值是14,恰好是7的2倍,这么看的话,每次数组要开到2n,这就极大的浪费了内存空间。
让我们用c++的STL队列来解决这个问题。
代码依旧简单,可读性也增强了不少!对于c++的STL库,不了解的可以去查查资料。
![](https://img-blog.csdn.net/20160717012405304)
样例输入:5
1 2 3 4 5
5
5 4 1 2 3
6
6 5 4 3 2 1
样例输出:
Yes
No
Yes
分析:中转站C的规则其实就是栈这个数据结果的特点!
[b]打印结果
![](https://img-blog.csdn.net/20160717014706481)
代码原理也很简单,输出结果是Yes只有两种情况,一种是正序,一种就是逆序!
/** *@author StormMaybin *@Date 2016-07-17 */
最近一段时间会对数据结构的知识和算法基础进行总结,尽量一天一更!如果时间错不开的话,第二天会补上。
数据结构中,栈和队列是最基础的也是简单的,一种是先进后出的线性数据结构,另外一种是先进先出的线性数据结构!
案例一:卡片游戏(队列)
题目说明:假设桌上有一叠扑克牌,依次编号为1-n(从最上面开始)。当至少还有两张的时候,可以进行操作:把第一张牌扔掉,然后把新的第一张放到整叠牌的最后。输入n,输出每次要扔掉的牌,以及最后剩下的牌。样例输入:7
样例输出:1 3 5 7 4 2 6
分析:先开始是扔掉1,然后把2排到最后,然后扔掉3,把4排到最后······,我们会很自然的想到队列,就像排队一样,银行柜台前,第一个人先排的队,然后第一个人办完事之后第一个走······
代码实现1:
# include <stdio.h> const int MAXN = 50; int queue[MAXN] = {0}; int main (void) { int n, front, rear; scanf ("%d",&n); for (int i = 0; i < n; i++) { queue[i] = i + 1; } front = 0; rear = n; while (front < rear) { printf ("%d ", queue[front++]); queue[rear++] = queue[front++]; } return 0; }
运行结果:
单看这个程序的输出结果,没有任何错误,答案就是我们想要的,现在让我们看看rear的值到最后是多大?
rear 的值是14,恰好是7的2倍,这么看的话,每次数组要开到2n,这就极大的浪费了内存空间。
让我们用c++的STL队列来解决这个问题。
代码实现2:
# include <cstdio> # include <queue> using namespace std; queue <int> q; int main (void) { int n; scanf ("%d", &n); for (int i = 0; i < n; i++) { //初始化队列 q.push(i+1); } while (! q.empty()) { //打印队首元素 printf ("%d ", q.front()); //抛弃首元素 q.pop(); //把队首元素加到队尾 q.push(q.front()); //抛弃队首元素 q.pop(); } return 0; }
代码依旧简单,可读性也增强了不少!对于c++的STL库,不了解的可以去查查资料。
案例二:铁轨(栈)
假设有一个火车站,有n节车厢标记为1-n;现在要按照某种特定的顺序进入B铁轨驶出车站,为了重组车厢的顺序,你现在有一个中转站C(station),在中转站C里面,你可以停放任意数量的车厢,但是有一个规则就是:C的末端是封顶的,驶入C的车厢必须按照相反的顺序驶出中转站C,一旦从A->C,你就不能退回到A,同理C->B!样例输入:5
1 2 3 4 5
5
5 4 1 2 3
6
6 5 4 3 2 1
样例输出:
Yes
No
Yes
分析:中转站C的规则其实就是栈这个数据结果的特点!
代码实现1:
/** *@author StormMaybin *@Date 2016-07-17 */
# include <stdio.h>
const int MAXN = 1000 + 10;
int n, target[MAXN];
int main (void)
{
while (scanf("%d",&n) == 1)
{
int stack[MAXN];
int top = 0;
int A = 1;
int B = 1;
for (int i = 1; i <= n; i++)
{
scanf ("%d", &target[i]);
}
int ok = 1;
while (B <= n)
{
if (A == target)
{
A++;
B++;
}
else if (top && stack[top] == target[B])
{
top--;
B++;
}
else if (A <= n)
{
stack[++top] = A++;
}
else
{
ok = 0;
break;
}
}
printf ("%s\n",ok ? "Yes" : "No");
}
return 0;
}
[b]打印结果
代码原理也很简单,输出结果是Yes只有两种情况,一种是正序,一种就是逆序!
代码实现2:
接着,用c++STL库来写:/** *@author StormMaybin *@Date 2016-07-17 */
# include <cstdio>
# include <stack>
using namespace std;
const int MAXN = 1000 + 10;
int n;
int target [MAXN];
int main (void)
{
while (scanf ("%d",&n) == 1)
{
stack<int> s;
int A = 1;
int B = 1;
for (int i = 1; i <= n; i++)
{
scanf ("%d", &target[i]);
}
int ok = 1;
while (B <= n)
{
if (A == target[B])
{
A++;
B++;
}
else if (! s.empty() && s.top() == target[B])
{
s.pop();
B++;
}
else if (A <= n)
{
s.push(A++);
}
else
{
ok = 0;
break;
}
}
printf("%s\n", ok ? "Yes" : "No");
}
return 0;
}
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#数据结构之顺序表(SeqList)实例详解
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- Lua教程(七):数据结构详解
- C#算法函数:获取一个字符串中的最大长度的数字
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#线程队列用法实例分析
- C#实现的算24点游戏算法实例分析