数据结构之队列(案例版)

队列是一种特殊性的线性结构,它只允许在队列的首部(head)进行删除操作,这个称作”出队”,而在队列的尾部(tail)进行插入工作,叫做”入队”。这就是我们常说的”先进先出“原则。生活中有很多的这样的案例,例如我们排队买火车票,每个排队买票的窗口就是一个队列,人越靠前就越早买到火车票,越早买完就越早从队列出来,后来的在队尾进入。

为了让大家更好的理解队列,在这里简单的介绍一个案例(这个案例来自《啊哈!算法》,写的非常通俗易懂,推荐初学者可以看看)。

假如:你遇见你喜欢的女神,想问她要QQ号,但是女神不想直接给你,对QQ号进行了相应的加密,同时也把加密的规则告诉你了。规则是这样的:首先将第1个数删除,紧接着将第2个数放到这串数的最后一个数,在将第3个数删除并将第4个数放到队尾,—–直到剩下最后一个数麻将最后一个数删除。按照刚才删除的顺序,把这些删除的数连接在一起就是女神的QQ。是不是追女神特别不容易!加密后的数是”7,3,3,8,5,7,8,4,8”.

好啦,现在该你了,怎样才能破解女神的QQ号呢,如果没有理解错解密规则的话女神的QQ号”735888473”。

其实解密的过程就像”排队”。从前面拿两个,第一个扔掉,第二个放到尾部。具体的过程是这样的:”7 3 3 8 5 7 8 4 8”,首先删除7并将3放到最后,这串数变成”3 8 5 7 8 4 8 3”,一次往下类推就能能得到女神的QQ号”735888473”.(其实这是我的QQ号,如果愿意技术交流的话欢迎添加)

下面用C简单的实现了解密 的效果:

#include <stdio.h>
int main()
{
    int q[100] = {0,7,3,3,8,5,7,8,4,8};
    //初始化队列
    int 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代表队尾的下一个位置。那为什么tail不直接记录队尾呢?这是因为当队列只剩一个元素时队首和队尾重合会带来一些麻烦。我们这里规定队首和队列重合时,队列为空,然后跳出循环。

队列是广度优先搜索以及队列优先的Bellman-Ford最短路算法的核心数据结构。为了更好的理解,现在将队列的三个基本要素(一个数组,两个变量)封装为一个结构体。

#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;
}

上面的这种写法虽然有点冗余,但可以加强对队列的认识。本篇文章只是举例简单的介绍了队列,如果想更多的了解一下队列的知识,请查看其他的文档,后续博主也会单独写一篇更加详细的文档。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
队列是一种先进先出(FIFO)的数据结构,常用于模拟排队等场景。下面是一个使用队列的实际案例: 假设我们有一个超市的收银台,需要处理顾客的结账请求。我们可以使用队列来模拟这个过程。当顾客来到收银台时,将其加入队列中,然后依次处理队列中的顾客,直到所有顾客都结账完成。 以下是使用C语言实现队列的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义队列结构 typedef struct { int* array; // 存储数据的数组 int front; // 队头指针 int rear; // 队尾指针 int size; // 队列当前元素个数 int capacity; // 队列容量 } Queue; // 初始化队列 void initializeQueue(Queue* queue, int capacity) { queue->array = (int*)malloc(capacity * sizeof(int)); queue->front = 0; queue->rear = -1; queue->size = 0; queue->capacity = capacity; } // 判断队列是否为空 int isEmpty(Queue* queue) { return queue->size == 0; } // 判断队列是否已满 int isFull(Queue* queue) { return queue->size == queue->capacity; } // 入队操作 void enqueue(Queue* queue, int item) { if (isFull(queue)) { printf("队列已满,无法入队!\n"); return; } queue->rear = (queue->rear + 1) % queue->capacity; queue->array[queue->rear] = item; queue->size++; } // 出队操作 int dequeue(Queue* queue) { if (isEmpty(queue)) { printf("队列为空,无法出队!\n"); return -1; } int item = queue->array[queue->front]; queue->front = (queue->front + 1) % queue->capacity; queue->size--; return item; } // 获取队头元素 int getFront(Queue* queue) { if (isEmpty(queue)) { printf("队列为空!\n"); return -1; } return queue->array[queue->front]; } // 获取队尾元素 int getRear(Queue* queue) { if (isEmpty(queue)) { printf("队列为空!\n"); return -1; } return queue->array[queue->rear]; } // 主函数测试 int main() { Queue queue; initializeQueue(&queue, 5); enqueue(&queue, 1); enqueue(&queue, 2); enqueue(&queue, 3); printf("队头元素:%d\n", getFront(&queue)); printf("队尾元素:%d\n", getRear(&queue)); dequeue(&queue); dequeue(&queue); printf("队头元素:%d\n", getFront(&queue)); printf("队尾元素:%d\n", getRear(&queue)); return 0; } ``` 这个示例展示了如何使用数组实现一个循环队列。我们首先定义了一个结构体 `Queue`,包含了队列的相关信息。然后通过相应的函数来实现入队、出队、获取队头元素等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值