C语言设计循环双端队列
题目描述
你的实现需要支持以下操作:
MyCircularDeque(k):构造函数,双端队列的大小为k。
insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。
insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。
deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。
deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。
getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。
getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。
isEmpty():检查双端队列是否为空。
isFull():检查双端队列是否满了。
设计思路
存储结构如下:
typedef struct {
int *data;
int head;
int tail;
int capacity;
} MyCircularDeque;
实现该循环队列,需要注意以下几点:
- 判断队列为空? 当收尾指针相等,队列为空,head == tail
- 判断队列已满? 当尾指针的下一位等于头指针,队列已满,(tail + 1 + capacity) % capacity == head;
- 初始化队列时? 首尾指针从0开始, head = tail = 0
- 从头部插入数据? head 指针向前移动, head = (head - 1 + capacity) % capacity
- 从尾部插入数据? tail 指针向后移动, tail = (tail + 1) % capacity
- 从头部删除数据? head 指针向后移动, head = (head + 1) % capacity
- 从尾部删除数据? tail 指针向前移动, tail = (tail - 1 + capacity) % capacity
- 从尾部读取数据? 考虑头部插入(head 前移一位)和尾部插入(插入后,tail后移一位),所以读取data[(tail - 1 + capacity) % capacity]
代码实现
本题目选自 Leetcode 641 题,以下为 C 语言实现代码
实现细节学习引用 Leetcode 题解,题解入口
typedef struct {
int *data;
int head;
int tail;
int capacity;
} MyCircularDeque;
// 建立双端循环队列及初始化
MyCircularDeque* myCircularDequeCreate(int k) {
MyCircularDeque *Dq = (MyCircularDeque *)malloc(sizeof(MyCircularDeque));
if(!Dq)
return NULL;
Dq -> data = (int *)malloc(sizeof(int) * (k + 1));
if(!Dq -> data)
return NULL;
Dq -> head = 0;
Dq -> tail = 0;
Dq -> capacity = k + 1;
return Dq;
}
bool myCircularDequeIsFull(MyCircularDeque* obj);
// 从队头插入数据,成功返回true
bool myCircularDequeInsertFront(MyCircularDeque* obj, int value) {
if(myCircularDequeIsFull(obj)) {
return false;
}
obj -> head = (obj -> head - 1 + obj -> capacity) % obj -> capacity;
obj -> data[obj -> head] = value;
return true;
}
// 从队尾插入数据,成功返回true
bool myCircularDequeInsertLast(MyCircularDeque* obj, int value) {
if(myCircularDequeIsFull(obj)) {
return false;
}
obj -> data[obj -> tail] = value;
obj -> tail = (obj -> tail + 1) % obj -> capacity;
return true;
}
bool myCircularDequeIsEmpty(MyCircularDeque* obj);
// 从队头删除数据,成功返回true
bool myCircularDequeDeleteFront(MyCircularDeque* obj) {
if(myCircularDequeIsEmpty(obj)) {
return false;
}
obj -> head = (obj -> head + 1) % obj -> capacity;
return true;
}
//从队尾删除数据,成功返回true
bool myCircularDequeDeleteLast(MyCircularDeque* obj) {
if(myCircularDequeIsEmpty(obj)) {
return false;
}
obj -> tail = (obj -> tail - 1 + obj -> capacity) % obj -> capacity;
return true;
}
// Get the front item from the deque
int myCircularDequeGetFront(MyCircularDeque* obj) {
if(myCircularDequeIsEmpty(obj)) {
return -1;
}
return obj -> data[obj -> head];
}
// Get the last item from the deque
int myCircularDequeGetRear(MyCircularDeque* obj) {
if(myCircularDequeIsEmpty(obj)) {
return -1;
}
return obj -> data[(obj -> tail - 1 + obj -> capacity) % obj -> capacity];
}
// Checks whether the circular deque is empty or not.
bool myCircularDequeIsEmpty(MyCircularDeque* obj) {
return (obj -> head == obj -> tail);
}
// Checks whether the circular deque is full or not
bool myCircularDequeIsFull(MyCircularDeque* obj) {
return ((obj -> tail + 1) % obj -> capacity == obj -> head);
}
void myCircularDequeFree(MyCircularDeque* obj) {
free(obj -> data);
obj -> data = NULL;
free(obj);
obj = NULL;
}
所有博客均在CSDN首发 Caso_卡索 https://blog.csdn.net/xiaoma_2018