码迷,mamicode.com
首页 > 其他好文 > 详细

西风的数据结构教程(2)——队列

时间:2015-04-16 23:46:11      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:数据结构   教程   队列   循环队列   

队列是一种简单的先进先出结构,各种需要排队的事情,都可以开一个队列来完成。
利用链表或数组,都能实现队列,不过最大的区别就是,数组的扩展比较困难,而链表较为容易,但链表资源消耗稍多。

数据结构的不同导致了队列的实现也不相同,链表上次已经实现过了,只需简单包装即可使用,这里,我们介绍简单的用数组模拟队列的方式:

技术分享

这个队列是固定长度的一个数组构建的,另外保存两个int数字,负责记录数组的下标索引。

我们下面就来编写一下这个队列,还是使用C语言,在此,我会继续介绍C语言的基础知识。

队列实现

复习一下上次的知识,C语言定义基本结构和宏定义,我们也先对队列进行必要的定义

/* queue.h */
#ifndef QUEUE_H
#define QUEUE_H

#include "malloc.h"

typedef char bool;
typedef int QueueElementType;
#define QueueSize 200

typedef struct _queue
{
    int head, tail;
    QueueElementType data_array[QueueSize];
} queue;

#endif // QUEUE_H

注意这里,我们提前设置了队列的长度,对于不知道队列具体应该多长的问题,可能并不大合适,不过过后我们会介绍如何计算队列需要的最大长度。

依旧是定义四个函数:

/* 队列的构造函数 */
queue* QueueCreate(); 

/* 从结尾压入元素 */
void QueuePush(queue* q, QueueElementType data);

/* 从头部弹出元素 */
QueueElementType QueuePop(queue* q);

/* 判断队列是否为空 */
bool QueueIsEmpty(queue* q);

比较简单的构造函数和判断函数这里直接给出,注意初始化的条件是头尾指针皆为0:

queue* QueueCreate() {
    queue* q = (queue*) malloc(sizeof(queue));
    q->head = 0;
    q->tail = 0; 
    return q;
}

bool QueueIsEmpty(queue* q) {
    return q->head == q->tail;
}

至于压入弹出也很简单,但需要注意的是,为了减少内存消耗,我们希望这个队列是循环队列。
(PS. 当年的唐山一中TSOI,有一句经典搞笑语录,“队列是先进先出的,循环队列是进进出出的。” 哎,跑题了,大家无视无视。)

至于什么是循环队列,大家请看下面这张图:

技术分享

恩,通过模运算就让队列循环运动,很方便的设计,不过还是要注意,永远不要让tail追上head,那时,队列就溢出了。
所以,我们的操作函数Push和Pop是这样的:

void QueuePush(queue* q, QueueElementType data) {
    q->data_array[ q->tail ] = data;
    q->tail = ++(q->tail) % QueueSize;
}


QueueElementType QueuePop(queue* q) {
    if (QueueIsEmpty(q)) return (QueueElementType)NULL;
    QueueElementType data = q->data_array[ q->head ];
    q->head = ++(q->head) % QueueSize;
    return data;
}

队列的使用当然十分简单,只需要操作这四个函数即可:

#include <stdio.h>
#include "queue.h"

queue* q = NULL;
int main() {
    q = QueueCreate();
    QueuePush(q, 10);
    QueuePush(q, 20);
    QueuePush(q, 30);

    printf("%d\n", QueuePop(q));
    printf("%d\n", QueuePop(q));
    printf("%d\n", QueuePop(q));
    return 0;
}

完整的代码详见附录,这里就不再具体多说了。

队列的应用

说了队列的写法,那么应该介绍一下,队列都有哪些用途。广搜问题,是让我最早认识队列的问题,这里就给大家举一个迷路小孩回家问题吧= =,画着X的地方表示无法通行,给他找一条可行的路径。

技术分享

开一个队列,记录已经走的步数和当前的位置,然后根据地图结构,每次看队列新弹出的元素的位置,分别向四个方向搜索,如果已经搜索过的就不要找了,整个搜索过程就像漫水一样,这样就能找到可行的路径了。
怎么样,这就是搜索问题中经典的广度优先遍历,是不是也很简单呢?

西风的数据结构教程(2)——队列

标签:数据结构   教程   队列   循环队列   

原文地址:http://blog.csdn.net/xfxyy_sxfancy/article/details/45082555

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!