《啊哈算法》——栈、队列、链表
通过题目我们可以看出这篇文章将介绍什么,栈、队列、链表本质上是数据结构中的东西,通过这章的学习能够给今后数据结构的学习打下一点基础。
队列:
我们通过一个简单的谜题来引入队列的概念,给出一串9位的加密QQ号,对于这串数字,删除第一位数字,然后将第二位数字放到这串数字的最后。反复操作,直到这一串数字的所有数字都被删除。在这个过程中,按照数字删除先后顺序排列的9位数字的便是解密后的QQ号,请问解密后的QQ号是多少?
其实从数学原理的角度,这个问题并没有什么难度,非常好理解,但关键在于,如何通过程序来高效的计算呢?
这里便用到队列的概念。我们将这9个数字看成一个有顺序的队并用数组记录,用变量head和tail记录这个队的队首和队尾后面的一个元素(为了方便判断队列为空,将tail指向队尾后面的元素),容易看到,我们对这个含有9个字符串的队列进行的操作本质上就是入队和出队,所谓入队即在队尾后添加一个元素,所谓出队即删除一个头元素。那么我们基于这样一个简单的数据结构,便可以很好的完成上面解密QQ号的模拟运算了。
#include<stdio.h> struct queue { int data[100]; int head , tail; }; int main() { struct queue q; int i; q.head = 1; q.tail = 1; for(i = 1;i <= 9;i++) { scanf("%d",&q.data[q.tail]); q.tail++; } while(q.head < q.tail) { printf("%d",q.data[q.head]); q.head++; q.data[q.tail] = q.data[q.head]; q.tail++; q.head++; } return 0; }
栈:
我们从一个具体的问题来引入对栈的应用——回文判断。所谓回文字符串即从左向右读和从右向左读的结果是一样的,例如ahaha就是“回文”的,那么现在给出一个字符串,如何通过编程来判断其是不是回文的呢?
我们通过一个生活的模型来引入栈模型,生活中我们常见的桶薯片,假设其中放入了n个薯片,编号为1~n,加工的时候,我们依次将1、2、3……n号薯片放入桶里的“小抽屉”,这便是一个入栈过程。那么现在很幸运这桶薯片被编号的薯片被你买到,于是你打开包装,首先开始吃第n号薯片,接下来是n-1、n-2……,这便是一个出栈的过程。与我们上文介绍的队列简单的对比一下,队列中的元素是先入先出,而栈中的元素是后入先出。
与队列类似,栈只需要基于一个一维数组和一个指向栈顶的变量top即可,
那么回到一开始的问题,对于一个字符串,我们找到其终点将其一分为二,记做s1和s2,将其中一个字符串s1入栈,然后按照出栈的顺序来读并将其与s2进行比较,如果相同,表明这个字符串是回文的。
简单的参考代码如下。
#include<cstdio> #include<cstring> using namespace std; int main() { char a[101] , s[101]; int i , len , mid , next , top; gets(a); len = strlen(a); mid = len/2 - 1; top = 0; for(i = 0;i <= mid;i++) s[++top] = a[i]; if(len % 2 == 0) next = mid + 1; else next = mid + 2; for(i = next;i <= len - 1;i++) { if(a[i] != s[top]) break; top--; } if(top == 0) printf("YES"); else printf("NO"); return 0; }