设计循环双端队列

题目描述

你的实现需要支持以下操作:
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;

实现该循环队列,需要注意以下几点:

  1. 判断队列为空? 当收尾指针相等,队列为空,head == tail
  2. 判断队列已满? 当尾指针的下一位等于头指针,队列已满,(tail + 1 + capacity) % capacity == head;
  3. 初始化队列时? 首尾指针从0开始, head = tail = 0
  4. 从头部插入数据? head 指针向前移动, head = (head - 1 + capacity) % capacity
  5. 从尾部插入数据? tail 指针向后移动, tail = (tail + 1) % capacity
  6. 从头部删除数据? head 指针向后移动, head = (head + 1) % capacity
  7. 从尾部删除数据? tail 指针向前移动, tail = (tail - 1 + capacity) % capacity
  8. 从尾部读取数据? 考虑头部插入(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;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Caso_卡索

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值