循环队列概念很早接触了 但在细节方面一直有些迷糊
正好今天的每日一题是循环队列 总结了一下
关键以下两点:
1.对于front 和 rear的定义要明确
font指向的是队头有效元素的位置 而rear则指向的是队尾下一个有效元素的位置 这就导致一些差异
最主要的就是进行队尾插入时 要先进行赋值 q[rear] = value 而后移动rear 指针 因为根据rear指针的定义之前rear指针所指向的位置 正是此时元素应该插入的有效位置
然后根据rear 定义 那么返回队尾元素时 返回应该时rear-1这个位置的元素 而并非rear
2.空出一个有效位置作为哨兵 主要是为了区分队空和队满两种状态
这和rear指针的定义是紧密关联的
当 (rear + 1 % capacity) == front 代表 此时队列已满 可以这样理解 rear 代表下一个元素的有效位置 即下一个元素的有效位置已经是front了那么这样就代表队满了
同时根据上述定义 真正队满是 front != rear 所以队空的情况只能是 front == rear
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| class MyCircularDeque { private int front; private int rear; private int capacity;
private int [] q;
public MyCircularDeque(int k) { capacity = k + 1; front = 0; rear = 0; q = new int[capacity]; }
public boolean insertFront(int value) { if(isFull() == true ) return false; front = (front - 1 + capacity) % capacity; q[front] = value; return true; }
public boolean insertLast(int value) { if(isFull() == true) return false; q[rear] = value; rear = (rear + 1 + capacity)%capacity; return true; }
public boolean deleteFront() { if(isEmpty() == true) return false; front = (front + 1 + capacity) % capacity; return true; }
public boolean deleteLast() { if(isEmpty() == true) return false; rear = (rear - 1 + capacity) % capacity; return true; }
public int getFront() { if(isEmpty() == true) return -1; return q[front]; }
public int getRear() { if (isEmpty() == true) return -1; return q[(rear - 1 + capacity) % capacity]; }
public boolean isEmpty() { return front == rear; }
public boolean isFull() { return (rear + 1) % capacity == front; } }
|