|
1 | 1 | #include<iostream>
|
2 |
| -using namespace std; |
| 2 | +#include<memory> |
| 3 | +#include<cassert> |
3 | 4 |
|
4 | 5 | namespace my {
|
| 6 | + const char endl = '\n'; |
5 | 7 | /**
|
6 |
| - * parameterised type implementation using linked list |
7 |
| - * [value][next] -> [value][next] -> ... -> [value][next] -> [value][next] |
8 |
| - * (front Node) (intermediat Nodes) (rear Node) (dummy Node) |
| 8 | + * implementation using linked list |
| 9 | + * [value][next] -> [value][next] -> ... -> [value][next] |
| 10 | + * (front Node) (intermediat Nodes) (rear Node) |
9 | 11 | */
|
10 | 12 | template<typename T>
|
11 | 13 | struct Node {
|
12 | 14 | /**
|
13 | 15 | * next: will store right Node address
|
14 | 16 | */
|
15 | 17 | T value;
|
16 |
| - Node<T>* next; |
17 |
| - Node(const T& V) : value(V), next(nullptr) { } |
| 18 | + std::shared_ptr<Node<T>> next; |
| 19 | + Node(const T& V) : value(V) { } |
18 | 20 | };
|
19 | 21 |
|
20 | 22 | template<typename T>
|
21 | 23 | class queue {
|
22 | 24 | private:
|
23 | 25 | /**
|
24 |
| - * _front : points to left most node |
25 |
| - * count: keeps track of current number of elements present in queue excluding dummy Node |
26 |
| - * rear: points to most recent Node added into the queue, which is just left size of dummy Node |
| 26 | + * front_pointer: points to left most node |
| 27 | + * count: keeps track of current number of elements present in queue |
| 28 | + * rear_pointer: points to most recent Node added into the queue, which is right most Node |
27 | 29 | */
|
28 |
| - Node<T>* _front; |
29 |
| - Node<T>* rear; |
| 30 | + std::shared_ptr<Node<T>> front_pointer; |
| 31 | + std::shared_ptr<Node<T>> rear_pointer; |
30 | 32 | size_t count;
|
31 | 33 | public:
|
32 |
| - queue() : _front(nullptr), rear(nullptr), count(0ULL) { |
33 |
| - _front = rear = new Node<T>(0); // creating a dummy Node |
34 |
| - } |
| 34 | + queue() : count(0ULL) { } |
35 | 35 |
|
36 | 36 | void push(const T& element) {
|
37 |
| - Node<T>* new_node = new Node<T>(element); // create New Node |
| 37 | + auto new_node = std::make_shared<Node<T>>(element); |
38 | 38 | if (count > 0) {
|
39 |
| - new_node->next = rear->next; // make new Node point to dummy Node |
40 |
| - rear->next = new_node; // make rear Node point to new Node |
41 |
| - rear = new_node; // make rear Node's pointer to point to new Node |
| 39 | + new_node->next = front_pointer; |
| 40 | + front_pointer = new_node; |
42 | 41 | } else {
|
43 |
| - new_node->next = rear; |
44 |
| - rear = _front = new_node; |
| 42 | + rear_pointer = front_pointer = new_node; |
45 | 43 | }
|
46 | 44 | count = count + 1;
|
47 | 45 | }
|
48 | 46 |
|
49 | 47 | void dequeue() {
|
50 |
| - if (count > 0) { |
51 |
| - Node<T>* buffer = _front; |
52 |
| - _front = _front->next; |
| 48 | + if (count > 1) { |
| 49 | + front_pointer = front_pointer->next; |
| 50 | + count = count - 1; |
| 51 | + } else if (count == 1) { |
| 52 | + front_pointer.reset(); |
| 53 | + rear_pointer.reset(); |
53 | 54 | count = count - 1;
|
54 |
| - delete buffer; |
55 | 55 | }
|
56 |
| - rear = (count != 0) ? rear : _front; |
57 | 56 | }
|
58 | 57 |
|
59 |
| - T& front() const { return _front->value; } |
60 |
| - T const& front() const { return _front->value; } |
| 58 | + T& front() { |
| 59 | + assert(count > 0 && "calling front on an empty queue"); |
| 60 | + return front_pointer->value; |
| 61 | + } |
| 62 | + |
| 63 | + T const& front() const { |
| 64 | + assert(count > 0 && "calling front on an empty queue"); |
| 65 | + return front_pointer->value; |
| 66 | + } |
61 | 67 |
|
62 | 68 | size_t size() const { return count; }
|
63 | 69 |
|
64 | 70 | bool empty() const { return count == 0; }
|
65 | 71 |
|
66 | 72 | ~queue() {
|
67 |
| - for (Node<T>* pointer = _front; pointer != nullptr;) { |
68 |
| - Node<T>* buffer = pointer; |
69 |
| - pointer = pointer->next; |
70 |
| - delete buffer; |
| 73 | + while (front_pointer.get() != nullptr) { |
| 74 | + front_pointer = front_pointer->next; |
71 | 75 | }
|
72 | 76 | }
|
73 | 77 | };
|
74 | 78 | }
|
75 | 79 |
|
76 | 80 | int main() {
|
77 | 81 | my::queue<int> Q;
|
78 |
| - |
79 | 82 | Q.push(0);
|
80 |
| - Q.push(1); |
81 |
| - Q.push(2); |
82 | 83 | Q.push(3);
|
83 |
| - cout << "count: " << Q.size() << endl; |
| 84 | + std::cout << "count: " << Q.size() << my::endl; |
84 | 85 | Q.front() = 10;
|
85 | 86 |
|
86 | 87 | while (Q.empty() != true) {
|
87 |
| - cout << "element: " << Q.front() << endl; |
88 |
| - Q.dequeue(); |
89 |
| - } |
90 |
| - |
91 |
| - Q.push(3); |
92 |
| - Q.push(6); |
93 |
| - cout << "count: " << Q.size() << endl; |
94 |
| - while (Q.empty() != true) { |
95 |
| - cout << "element: " << Q.front() << endl; |
| 88 | + std::cout << "element: " << Q.front() << my::endl; |
96 | 89 | Q.dequeue();
|
97 | 90 | }
|
98 | 91 | return 0;
|
99 | 92 | }
|
100 |
| - |
0 commit comments