【坐在马桶上看算法】算法4:队列——解密QQ号

        新学期开始了,小哈是小哼的新同桌(小哈是个小美女哦~),小哼向小哈询问QQ号,小哈固然不会直接告诉小哼啦,缘由嘛你懂的。因此小哈给了小哼一串加密过的数字,同时小哈也告诉了小哼解密规则。规则是这样的:首先将第1个数删除,紧接着将第2个数放到这串数的末尾,再将第3个数删除并将第4个数再放到这串数的末尾,再将第5个数删除……直到剩下最后一个数,将最后一个数也删除。按照刚才删除的顺序,把这些删除的数连在一块儿就是小哈的QQ啦。如今你来帮帮小哼吧。小哈给小哼加密过的一串数是“6 3 1 75 8 9 2 4”。
 
        OK,如今轮到你动手的时候了。快去找出9张便签或小纸片,将“6 3 1 75 8 9 2 4”这9个数分别写在9张便签上,模拟一下解密过程。若是你没有理解错解密规则的话,解密后小哈的QQ号应该是“6 1 5 94 7 2 8 3”。
        其实解密的过程就像是将这些数“排队”。每次从最前面拿两个,第1个扔掉,第2个放到尾部。具体过程是这样的:刚开始这串数是“6 3 1 75 8 9 2 4”,首先删除 6并将3放到这串数的末尾,这串数更新为“1 7 5 89 2 4 3”。接下来删除 1并将7放到末尾,即更新为“5 8 9 24 3 7”。再删除 5并将8放到末尾即“9 2 4 3 7 8”,删除 9并将2放到末尾即“4 3 7 8 2”,删除 4并将3放到末尾即“7 8 2 3”,删除 7并将8放到末尾即“2 3 8”,删除 2并将3放到末尾即“8 3”,删除 8并将3放到末尾即“3”,最后删除 3。所以被删除的顺序是“ 6 1 5 9 4 7 2 8 3”,这就是小哈的QQ号码了,你能够加她试试看^_^。
        既然如今已经搞清楚了解密法则,不妨本身尝试一下去编程,我相信你必定能够写出来的。
        首先须要一个数组来存储这一串数即intq[101]。并初始化这个数组即intq[101]={0,6,3,1,7,5,8,9,2,4};(此处初始化是我多写了一个0,用来填充q[0],由于我比较喜欢从q[1]开始用,对数组初始化不是很理解的同窗能够去看下个人上一本书《啊哈C!思考快你一步》)接下来就是模拟解密的过程了。
        解密的第一步是将第一个数删除,你能够想一下如何在数组中删除一个数呢?最简单的方法是将全部后面的数都往前面挪动一位,将前面的数覆盖。就比如咱们在排队买票,最前面的人买好离开了,后面全部的人就须要所有向前面走一步,补上以前的空位,可是这样的作法很耗费时间。
 

 

        在这里,我将引入两个整型变量head和tail。head用来记录队列的队首(即第一位),tail用来记录队列的队尾(即最后一位)的下一个位置。你可能会问为何tail不直接记录队尾,却要记录队尾的下一个位置呢?这是由于当队列当中只剩下一个元素时,队首和队尾重合会带来一些麻烦。咱们这里规定队首和队尾重合时,队列为空。
        如今有9个数,9个数所有放入队列以后head=1;tail=10;此时head和tail之间的数就是目前队列中“有效”的数。若是要删除一个数的话,就将head++就OK了,这样仍然能够保持head和tail之间的数为目前队列中“有效”的数。这样作虽然浪费了一个空间,却节省了大量的时间,这是很是划算的。新增长一个数也很简单,把须要增长的数放到队尾即q[tail]以后再tail++就欧克啦。
 
        咱们来小结一下,在队首删除一个数的操做是head++;
        在队尾增长一个数(假设这个数是x)的操做是q[tail]=x;tail++;
        整个解密过程,请看下面这个霸气外漏的图。
 
        最后的输出就是6 1 5 94 7 2 8 3,代码实现以下。
#include <stdio.h>
int main()
{
    int q[102]={0,6,3,1,7,5,8,9,2,4},head,tail;
    int i;
    //初始化队列
    head=1;
    tail=10; //队列中已经有9个元素了,tail执向的队尾的后一个位置   
    while(head<tail) //当队列不为空的时候执行循环
    {
        //打印队首并将队首出队
        printf("%d ",q[head]);
        head++;
        //先将新队首的数添加到队尾
        q[tail]=q[head];
        tail++;
        //再将队首出队
        head++;
    }
   
    getchar();getchar();
    return 0;
}

 

        怎么样上面的代码运行成功没有?如今咱们再来总结一下队列的概念。队列是一种特殊的线性结构,它只容许在队列的首部(head)进行删除操做称之为“出队”,而在队列的尾部(tail)进行插入操做称之为“入队”。当队列中没有元素时(即head==tail),称为空队列。在咱们的平常生活中有不少状况都符合队列的特性。好比咱们以前提到过的买票,每一个排队买票的窗口就是一个队列。在这个队列当中,新来的人老是站在队列的最后面,来的越早的人越靠前也就越早能买到票,就是先来的人先服务,咱们称为“先进先出”(First InFirst Out,FIFO)原则。
        队列将是咱们从此学习广度优先搜索以及队列优化的Bellman-Ford最短路算法的核心数据结构。因此如今将队列的三个基本元素(一个数组,两个变量)封装为一个结构体类型,以下。
struct queue
{
    int data[100];//队列的主体,用来存储内容
    int head;//队首
    int tail;//队尾
};

 

        上面咱们定义了一个结构体类型,咱们一般将其放在main函数的外面,请注意结构体的定义末尾有个;号。struct是结构体的关键字,queue是咱们为这个结构体起的名字。这个结构体有三个成员分别是:整型数组data、整型head和整型tail。这样咱们就能够把这三个部分放在一块儿做为一个总体来对待。你能够这么理解:咱们定义了一个新的数据类型,这个新类型很是强大,用这个新类型定义出的每个变量能够同时存储一个整型数组和两个整数。
 
 
        有了新的结构体类型,如何定义结构体变量呢?很简单,这与咱们以前定义变量的方式是同样,以下。
struct queue q;

 

        请注意struct queue须要总体使用,不能直接写queue q;这样咱们就定义了一个结构体变量q。这个结构体变量q就能够知足队列的全部操做了。那又该如何访问结构体变量的内部成员呢?可使用.号,它叫作成员运算符或者点号运算符,以下:
q.head=1;
q.tail=1;
scanf("%d",&q.data[q.tail]);

 

        好了,下面这段代码就是使用结构体来实现的队列操做。
#include <stdio.h>
struct queue
{
    int data[100];//队列的主体,用来存储内容
    int head;//队首
    int tail;//队尾
};
int main()
{
    struct queue q;
    int i;
    //初始化队列
    q.head=1;
    q.tail=1;
    for(i=1;i<=9;i++)
    {
        //依次向队列插入9个数
        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++;
    }
   
    getchar();getchar();
    return 0;
}

 

        上面的这种写法看起来虽然冗余了一些,可是能够增强你对队列这个算法的理解。C++的STL库已经有队列的实现,有兴趣的同窗能够参看相关材料。队列的起源已经没法追溯。在尚未数字计算机以前,数学应用中就已经有对队列的记载了。咱们生活中队列的例子也比比皆是,好比排队买票,又或者吃饭时候用来排队等候的叫号机,又或者拨打银行客服选择人工服务时,每次都会被提示“客服人员正忙,请耐心等待”,由于客服人员太少了,拨打电话的客户须要按照打进的时间顺序进行等候等等。这里表扬一下肯德基的宅急送,没有作广告的嫌疑啊,每次一打就通,基本不须要等待。可是我每次打银行的客服(具体是哪家银行就不点名了)基本都要等待很长时间,老是告诉我“正在转接,请稍后”,嘟嘟嘟三声后就变成“客服正忙,请耐心等待!”而后就给我放很难听的曲子。看来钱在谁那里谁就是老大啊……
 
码字不容易啊,转载麻烦注明出处

【一周一算法】解密QQ号——队列
http://bbs.ahalei.com/thread-4489-1-1.html
(出处: 啊哈磊_编程从这里起步)html

相关文章
相关标签/搜索