ggde

扭轱辘旋转的博客

无聊之人写的无聊文章
5
原创
0
转载
0
译文
1
评论
2436
访问
京 ICP 证 070598 号img

Copyright © 1999-2016,
CSDN.NET, All Rights Reserved

2016
六月
07

队列的数组实现与链表实现
分类:数据结构与算法

(393) (0) 编辑 删除

队列的说明

队列是一种基本的数据结构。我们平时排队等候服务的时候,是先到的人先接受服务。对于队列这种数据结构,实现的就是一种先进先出(first-int, first-out, FIFO)的策略。

改变队列中元素的操作方法只有两个——push与pop。push是把元素从队尾插入,pop是把元素从队头删除。

数组实现

队列的数组实现有两种形式,一种是线性实现,另一种是循环实现。

线性实现有一定的局限性,当rear抵达max-1的时候就不能再让元素入队了。此时front前面的空间将被浪费,因为没有被使用。

图片来自《Data Structures and Program Design In C++》

着重说说循环实现。

循环实现就是把一个数组看成一个循环的圆,当rear或front抵达max - 1的时候,再前进,将回到0处。这样一来,就能对数组的空间有充分的利用。

图片来自《Data Structures and Program Design In C++》

数组实现队列最大的问题在于,如何判断其边界,下面给出边界情况

图片来自《Data Structures and Program Design In C++》

在实现的时候,需要区分如何判断队列已满或者队列已空。
当rear的下一个位置是front的时候,则队列已满。

当rear和front的位置重叠,则队列已空。

这样就能避免图中出现的边界情况,难以判断满或空。

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
template
class Queue {
private:
static const int maxqueue = 10;
T entry[maxqueue + 1]; // 分配比maxqueue + 1的空间
// 实际上队列的可用空间还是maxque
int head;
int rear;
int queueSize;

bool full() const {
return (((rear + 1) % (maxqueue + 1)) == head)
&& (queueSize == maxqueue);
}

public:
Queue() : head(0), rear(0), queueSize(0) {
for (int i = 0; i < maxqueue + 1; i++)
entry[i] = T();
}

// 下面所以求余都是为了让rear和front的范围限定在[0, 10]

void push(const T &val) {
if (!full()) {
entry[rear] = val;
rear = (rear + 1) % (maxqueue + 1);
++queueSize;
}
}

void pop() {
if (!empty()) {
head = (head + 1) % (maxqueue + 1);
–queueSize;
}
}

T front() const {
if (!empty())
return entry[head];
}

T back() const {
if (!empty())
// rear-1是队列最后一个元素的位置
// rear-1可能是-1,所以将其跳转到maxqueue位置
return entry[(rear - 1 + (maxqueue + 1)) % (maxqueue + 1)];
}

bool empty() const {
return ((rear + 1) % (maxqueue + 1) == head) && (queueSize == 0);
}

int size() const {
return queueSize;
}
};

链表实现

链表实现利用两个结点,head记录链表头即队头,rear记录链表尾即队尾

图片来自《Data Structures and Program Design In C++》

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
template
class Queue {
private:
struct Node {
T data;
Node *next;
};

private:
Node *head;
Node *rear;
int queueSize;

public:
Queue() : head(NULL), rear(NULL), queueSize(0) { }

~Queue() {
while (!empty())
pop();
}

void push(const T &val) {
Node *new_node = new Node;
new_node->data = val;
new_node->next = NULL;
if (head == NULL && rear == NULL) {
head = rear = new_node;
} else {
rear->next = new_node;
rear = new_node;
}
++queueSize;
}

void pop() {
if (!empty()) {
Node *temp = head;
head = head->next;
delete temp;
–queueSize;
}
}

T front() const {
if (!empty())
return head->data;
}

T back() const {
if (!empty())
return rear->data;
}

bool empty() const {
return queueSize == 0;
}

int size() const {
return queueSize;
}
};

参考书籍

《Data Structures and Program Design In C++》
版权声明:本文为博主原创文章,未经博主允许不得转载。

顶0 踩0

栈的数组实现与链表实现分治策略之最大子数组问题
发表评论

发表评论

暂无评论

img
扭轱辘旋转

等级:

排名:千里之外

img

文章搜索
博客专栏
文章分类
文章存档
阅读排行
评论排行
推荐文章
最新评论
img

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值