队列
思考这样一个问题,你将实现一个称为“优先级队列”的数据结构,它允许你根据优先级来处理事物。 假设你将建立一个医院急诊室:优先考虑优先级别高的的患者先参加会诊,即使他们在其他患者之后到达:
举个例子:
- “Dolores” 优先级为 5
- “Bernard” 优先级为 4
- “Arnold” 优先级为 8
- “William” 优先级为 5
- “Teddy” 优先级为 5
- “Ford” 优先级为 2
这样,如果你想为这些病人治疗,那么就他们的治疗顺序应该是 * Ford, Bernard, Dolores, William, Teddy, Arnold.*
那么,你的任务是什么??没错,我们要建立一个队列!(Architect a Queue)
最简单的一个方法:
class QueueInt { // in QueueInt.h
public:
QueueInt (); // constructor,构造函数
void enqueue(int value); // append a value 在队伍尾部加入一个值
int dequeue(); // return the first-in value 返回队头
private:
Vector<int> data; // member variables 数字变量
};
我们现在来思考一下,dequeue功能具体的过程:
1. 假设我们有一个队列,为 1 2 3 4 5 6 7 8,那么初始状态是这样的
2. 当我们执行dequeue功能时,队头这时候便从队列中移除
3. 移除后,队头下一个数称为新的队头
同样的如果我们执行enqueue(42),那么情况应该是这样的:
1. 初始的队列为上面的队列:
2. 然后所有的数值都往队头方向前移一位,为队尾腾出空间插入(紫色代表的是所有的数字都向前移动了一位,绿色虽然还是1,但是我们将42赋值给它就好了):
3. 然后我们将42插入到队尾(即赋值给队尾),紫色部分就是我们组成的新的队列:
这个时候我们很容易得到,
**enqueue的算法复杂度为 O(1),因为我们只需要在队头插入一个元素,而不涉及其他操作。
dequeue的算法复杂度为 O(n),因为每排队到队尾,所有元素都要前移一位。**
我们是否可以做的更好?
让我们稍微往复杂的方向思考这个问题。假设有一个新的队列,8 9,你要往这个队列里面插入一个新的元素为7.结合我们之前所学的链表知识,我们可以这样去看:
1. 建立一个指向数据成员的指针 data,指向队尾。
2. 然后我们将指向队尾的指针,指向我们新的成员,然后新的成员指向上一个队尾
3.同样的方式 我们可以这样去插入 6:
现在这样,我们成功把上面的enqueue从O(n)变成了O(1)