trainings/AdvancedCppV2/Presentation/exercises/list/solution/list2.cpp

181 lines
3.6 KiB
C++

#include <iostream>
#include <memory>
#include <utility>
class Node {
public:
Node(const int value, std::unique_ptr<Node> next)
: next_(std::move(next)), value_(value) {}
explicit Node(const int v)
: Node(v, nullptr) {}
const Node* next() const { return next_.get(); }
Node* next() { return next_.get(); }
int value() const { return value_; }
void setNext(std::unique_ptr<Node> next) { next_ = std::move(next); }
std::unique_ptr<Node> getNext() { return std::move(next_); }
private:
std::unique_ptr<Node> next_;
int value_;
};
// ht
// 1
// h t
// 2 -> 1
// h t
// 3 -> 2 -> 1
// h t
// 4 -> 3 -> 2 -> 1
// h t
// 4 -> 3 -> 2 -> 1 -> 5
//
// 3 -> 2 -> 1 -> 5
// 3 -> 1 -> 5
class List {
public:
void pushFront(int value) {
if (!head_) {
pushHead(value);
return;
}
head_ = std::make_unique<Node>(value, std::move(head_));
}
void pushBack(int value) {
if (!tail_) {
pushHead(value);
return;
}
tail_->setNext(std::make_unique<Node>(value));
tail_ = tail_->next();
}
bool erase(int value) {
// Remove head
if (head_ && head_->value() == value) {
head_ = head_->getNext();
if (!head_) {
tail_ = nullptr;
}
return true;
}
if (auto* node = findPrevNode(value)) {
// Remove tail
if (node->next() == tail_) {
tail_ = node;
}
node->setNext(std::move(node->next()->getNext()));
return true;
}
return false;
}
const Node* findByValue(const int value) const {
const auto* current = head_.get();
while (current) {
if (current->value() == value) {
return current;
}
current = current->next();
}
return nullptr;
}
void print() const {
const auto* current = head_.get();
while (current) {
std::cout << current->value() << ' ';
current = current->next();
}
std::cout << '\n';
}
private:
// ht
// 1
// h t
// 2 -> 1
// h t
// 2 -> 1 -> 3
// 2 -> 3
void pushHead(int value) {
head_ = std::make_unique<Node>(value);
tail_ = head_.get();
}
Node* findPrevNode(const int value) const {
auto* current = head_.get();
Node* prev = nullptr;
while (current) {
if (current->value() == value) {
return prev;
}
prev = current;
current = current->next();
}
return nullptr;
}
std::unique_ptr<Node> head_;
Node* tail_{nullptr};
};
int main() {
List list;
list.pushFront(4);
list.pushFront(2);
list.pushFront(7);
list.pushFront(9);
list.print();
if (const auto* const node = list.findByValue(1)) {
std::cout << node->value() << '\n';
} else {
std::cout << "can't find node with value 1\n";
}
if (const auto* const node = list.findByValue(7)) {
std::cout << node->value() << '\n';
} else {
std::cout << "can't find node with value 7\n";
}
list.pushBack(10);
list.print();
list.pushBack(12);
list.pushFront(3);
list.pushFront(5);
list.pushBack(13);
list.print();
list.erase(2);
list.print();
list.erase(5);
list.print();
list.erase(13);
list.print();
list.erase(12);
list.print();
list.pushBack(40);
list.print();
return 0;
}