Skip to content

Commit

Permalink
Stack queue in cpp (algorithm-archivists#936)
Browse files Browse the repository at this point in the history
* adding c++ implementation of stack and queue

* improved some comments

* Update contents/stacks_and_queues/code/c++/queue.cpp

adding version T const& front() const

Co-authored-by: Dimitri Belopopsky <[email protected]>

* Update contents/stacks_and_queues/code/c++/queue.cpp

removing unnecessary comment

Co-authored-by: Dimitri Belopopsky <[email protected]>

* improved implementation

* fixed queue implementation

* renamed queue API push as enqueue

* Rename code folder to cpp

* Inline newlines

Co-authored-by: Dimitri Belopopsky <[email protected]>
Co-authored-by: Dimitri Belopopsky <[email protected]>
  • Loading branch information
3 people authored Jan 12, 2022
1 parent 015489e commit 28287e3
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 0 deletions.
91 changes: 91 additions & 0 deletions contents/stacks_and_queues/code/cpp/queue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include<iostream>
#include<memory>
#include<cassert>

namespace my {
/**
* implementation using linked list
* [value][next] -> [value][next] -> ... -> [value][next]
* (front Node) (intermediat Nodes) (rear Node)
*/
template<typename T>
struct Node {
/**
* next: will store right Node address
*/
T value;
std::shared_ptr<Node<T>> next;
Node(const T& V) : value(V) { }
};

template<typename T>
class queue {
private:
/**
* front_pointer: points to left most node
* count: keeps track of current number of elements present in queue
* rear_pointer: points to most recent Node added into the queue, which is right most Node
*/
std::shared_ptr<Node<T>> front_pointer;
std::shared_ptr<Node<T>> rear_pointer;
size_t count;
public:
queue() : count(0ULL) { }

void enqueue(const T& element) {
auto new_node = std::make_shared<Node<T>>(element);
if (count > 0) {
rear_pointer->next = new_node;
rear_pointer = new_node;
} else {
rear_pointer = front_pointer = new_node;
}
count = count + 1;
}

void dequeue() {
if (count > 1) {
front_pointer = front_pointer->next;
count = count - 1;
} else if (count == 1) {
front_pointer.reset();
rear_pointer.reset();
count = count - 1;
}
}

T& front() {
assert(count > 0 && "calling front on an empty queue");
return front_pointer->value;
}

T const& front() const {
assert(count > 0 && "calling front on an empty queue");
return front_pointer->value;
}

size_t size() const { return count; }

bool empty() const { return count == 0; }

~queue() {
while (front_pointer.get() != nullptr) {
front_pointer = front_pointer->next;
}
}
};
}

int main() {
my::queue<int> intQueue;
intQueue.enqueue(4);
intQueue.enqueue(5);
intQueue.enqueue(9);

int frontElement = intQueue.front();
intQueue.dequeue();
std::cout << frontElement << '\n';
std::cout << intQueue.size() << '\n';
std::cout << intQueue.front() << '\n';
return 0;
}
84 changes: 84 additions & 0 deletions contents/stacks_and_queues/code/cpp/stack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include<iostream>
#include<cassert>
#include<memory>

namespace my {
/**
* implementation using linked list
* [value][next] -> [value][next] -> ... -> [value][next]
* (top Node) (intermediat Nodes)
* left most Node represents top element of stack
*/
template<typename T>
struct Node {
/**
* next: will store right Node address
*/
T value;
std::unique_ptr<Node<T>> next;
Node(const T& V) : value(V) { }
};

template<typename T>
class stack {
private:
/**
* top_pointer: points to left most node
* count: keeps track of current number of elements present in stack
*/
std::unique_ptr<Node<T>> top_pointer;
size_t count;
public:
stack() : count(0ULL) { }

void push(const T& element) {
auto new_node = std::make_unique<Node<T>>(element);
new_node->next = std::move(top_pointer);
top_pointer = std::move(new_node);
count = count + 1;
}

void pop() {
if (count > 0) {
top_pointer = std::move(top_pointer->next);
count = count - 1;
}
}

T& top() {
assert(count > 0 and "calling top() on an empty stack");
return top_pointer->value;
}
// returning mutable reference can very be usefull if someone wants to modify top element

T const& top() const {
assert(count > 0 and "calling top() on an empty stack");
return top_pointer->value;
}

size_t size() const { return count; }

bool empty() const { return count == 0; }

~stack() {
while (top_pointer.get() != nullptr) {
top_pointer = std::move(top_pointer->next);
}
}
};
}

int main() {
my::stack<int> intStack;

intStack.push(4);
intStack.push(5);
intStack.push(9);

int topElement = intStack.top();
intStack.pop();
std::cout << topElement << '\n';
std::cout << intStack.size() << '\n';
std::cout << intStack.top() << '\n';
return 0;
}
6 changes: 6 additions & 0 deletions contents/stacks_and_queues/stacks_and_queues.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Here is a simple implementation of a stack:
{% sample lang="ts" %}
[import, lang:"typescript"](code/typescript/stack.ts)
{% sample lang="java" %}
[import, lang:"java"](code/java/Stack.java)
{% sample lang = "cpp"%}
[import, lang:"cpp"](code/cpp/stack.cpp)
[import, lang:"java"](code/java/StackTest.java)
{% sample lang="rust" %}
[import, lang:"rust"](code/rust/Stack.rs)
Expand All @@ -29,6 +32,9 @@ Here is a simple implementation of a queue:
{% sample lang="ts" %}
[import, lang:"typescript"](code/typescript/queue.ts)
{% sample lang="java" %}
[import, lang:"java" ](code/java/Queue.java)
{% sample lang = "cpp"%}
[import, lang:"cpp"](code/cpp/queue.cpp)
[import, lang:"java" ](code/java/QueueTest.java)
{% sample lang="rust" %}
[import, lang:"rust" ](code/rust/Queue.rs)
Expand Down

0 comments on commit 28287e3

Please sign in to comment.