做对的事情比把事情做对重要
/**
*@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[B])
{
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;
}
打印结果
代码原理也很简单,输出结果是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;
}