-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimplement_queue_using_stacks_test.dart
130 lines (93 loc) · 2.63 KB
/
implement_queue_using_stacks_test.dart
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/// Implement a first in first out (FIFO) queue using only two stacks.
/// The implemented queue should support all the functions of a normal queue
/// (push, peek, pop, and empty).
import 'dart:collection' as c;
import 'package:test/test.dart';
abstract class Stack<T> {
// Pushes element to the top of the stack.
void push(T value);
// Removes the element at the top of the stack and returns it.
T pop();
// Returns the element at the top of the stack.
peek();
// Returns true if the stack is empty, false otherwise.
bool get isEmpty;
}
abstract class Queue<T> {
// Pushes element [value] to the back of the queue.
void push(T value);
// Removes the element from the front of the queue and returns it.
T pop();
// Returns the element at the front of the queue.
T peek();
// Returns true if the queue is empty, false otherwise.
bool get isEmpty;
}
class CollectionStack<T> implements Stack<T> {
CollectionStack(this._internal);
final c.Queue<T> _internal;
@override
void push(T value) => _internal.addLast(value);
@override
T pop() => _internal.removeLast();
@override
T peek() => _internal.last;
@override
bool get isEmpty => _internal.isEmpty;
}
class DoubleStackQueue<T> implements Queue<T> {
DoubleStackQueue(this._pushStack, this._popStack,) : _phase = _Phase.push;
final Stack<T> _pushStack;
final Stack<T> _popStack;
_Phase _phase;
// [phase] is the new phase.
void _switchPhase(_Phase phase) {
if (_phase == phase) return;
if (phase == _Phase.push) {
while (!_popStack.isEmpty) _pushStack.push(_popStack.pop());
} else {
while (!_pushStack.isEmpty) _popStack.push(_pushStack.pop());
}
_phase = phase;
}
@override
void push(T value) {
_switchPhase(_Phase.push);
_pushStack.push(value);
}
@override
T pop() {
_switchPhase(_Phase.pop);
return _popStack.pop();
}
@override
T peek() {
_switchPhase(_Phase.pop);
return _popStack.peek();
}
@override
bool get isEmpty => _pushStack.isEmpty && _popStack.isEmpty;
}
enum _Phase { push, pop }
void main() {
group('implement queue using stacks', () {
test('fifo', () {
final queue = DoubleStackQueue<int>(
CollectionStack(c.ListQueue()),
CollectionStack(c.ListQueue()),
);
expect(queue.isEmpty, true);
queue.push(1);
queue.push(2);
queue.push(3);
expect(queue.isEmpty, false);
expect(queue.peek(), 1);
expect(queue.pop(), 1);
expect(queue.pop(), 2);
queue.push(4);
expect(queue.pop(), 3);
expect(queue.pop(), 4);
expect(queue.isEmpty, true);
});
});
}