算法导论第三版P131
题目:
10.1-5 栈插入和删除元素只能在同一端进行,队列的插入操作和删除操作分别在两端进行,与它们不同的,有一种双端队列(deque),其插入和删除操作都可以在两端进行。写出4个时间均为O(1)的过程,分别实现在双端队列插入和删除元素的操作,该队列使用一个数组实现的。
注意点:
1、左右端点指向的位置是类似于队列中的tail端点,是下一个插入操作的位置。
2、然后注意遍历的时候,左端点和右端点的位置关系,有两种可能,所以遍历的方式不一样。
代码:
/*
* 使用单数组实现双端队列
*/
#include <iostream>
using namespace std;
class deque {
int leftHead; //左端节点,指向下一个能操作的空位置
int rightHead; //右端节点
int len;
int* array;
public:
deque(int size) :
leftHead(0), rightHead(0), len(size) {
array = new int[size];
}
~deque() {
delete []array;
leftHead = rightHead = 0;
}
/*
* 获取上一个位置
*/
int pre(int pos) {
if (pos == 0) {
return len - 1;
} else {
return --pos;
}
}
/*
* 获取下一个位置
*/
int next(int pos) {
if (pos == len - 1) {
return 0;
} else {
return ++pos;
}
}
bool isEmpty() {
return leftHead == rightHead ? true : false;
}
/*
* 左边节点的插入
*/
void leftInsert(int k) {
int p = pre(leftHead);
if (p == rightHead) {
cout << "error:overflow" << endl;
return;
}
//如果是空的情况,则左右节点都需要移动
if (isEmpty()) {
rightHead = next(rightHead);
}
array[leftHead] = k;
leftHead = p;
}
void rightInsert(int k) {
int n = next(rightHead);
if (n == leftHead) {
cout << "error:oveflow" << endl;
return;
}
//如果是空的情况,则左右节点都需要移动
if (isEmpty()) {
leftHead = pre(leftHead);
}
array[rightHead] = k;
rightHead = next(rightHead);
}
/*
* 左端删除
*/
int leftDelete() {
if (isEmpty()) {
cout << "error:underflow" << endl;
return -1;
}
leftHead = next(leftHead);
//如果只有一个元素,则删除完之后,右端点也要移动,因为这时队列为空了
if (leftHead == pre(rightHead)) {
rightHead = leftHead;
}
return array[leftHead];
}
/*
* 右端删除
*/
int rightDelete() {
if (isEmpty()) {
cout << "error:underflow" << endl;
return -1;
}
rightHead = pre(rightHead);
//如果只有一个元素,则删除完之后,左端点也要移动,因为这时队列为空了
if (rightHead == next(leftHead)) {
leftHead = rightHead;
}
return array[rightHead];
}
void printDeque() {
cout << "leftHead=" << leftHead << ",rightHead=" << rightHead << endl;
if (isEmpty()) {
return;
}
//考虑leftHead和rightHead分别在左右的两种情况
if (leftHead < rightHead) {
for (int i = leftHead + 1; i < rightHead; i++) {
cout << "array[" << i << "]=" << array[i] << ' ';
}
cout << endl;
} else {
//leftHead > rightHead时的情况
for (int i = 0; i < rightHead; i++) {
cout << "array[" << i << "]=" << array[i] << ' ';
}
for (int i = leftHead + 1; i < len; i++) {
cout << "array[" << i << "]=" << array[i] << ' ';
}
cout << endl;
}
}
};
int main() {
deque* dq = new deque(5);
dq->leftDelete();
dq->leftInsert(4);
dq->rightInsert(6);
dq->printDeque();
cout << dq->leftDelete() << endl;
dq->printDeque();
return 0;
}