So then let's determine how you want the list to work.
You will want to add and delete elements, right?
let's call them...
pop_front, pop_back, push_front, push_back (insert for later)
and of course merge
all these elements return... hm... nothing
well, let's also print it.
And you may want to know if the list has elements or is empty.
In this merge Method, do you want the second list to be modified?
Do you want to be the second list valid after the Lists are merged?
Let's say we have 2 node pointers, one of them marks the beginning and one of them marks the end.
and we have a variable which counts the size
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
#include <iostream>
template <typename T>
class List
{
public:
struct Node
{
T value;
Node* next;
};
public:
List() : first(nullptr), last(nullptr), size(0) {}
bool pop_front()
{
if(empty())
return false;
Node* second = first->next;
delete first;
first = second;
if(first == nullptr) // if the last element is deleted
last = nullptr;
size--;
return true;
}
bool pop_back()
{
if(empty())
return false;
Node* prev = get_prev(last);
if(prev != nullptr) // if there was a previous node
prev->next = nullptr; //set the next of that to be nullptr, to clarify that this node has no next
delete last;
last = prev;
if(last == nullptr) // if the last element is deleted
first = nullptr;
size--;
return true;
}
void push_front(T value)
{
Node* node = new Node;
node->value = value;
node->next = first;
first = node;
if(empty()) // if the list was empty the last node is also that node
last = node;
size++;
}
void push_back(T value)
{
Node* node = new Node;
node->value = value;
node->next = nullptr; // last node
if(empty()) // if the list was empty the first node is also that node
first = node;
else
last->next = node; // set the currently last node that the next one is node
last = node;
size++;
}
void print() const
{
std::cout << "size: " << size << std::endl;
Node* temp = first;
while(temp != nullptr)
{
std::cout << temp->value << std::endl;
temp = temp->next;
}
}
void merge(const List<T>& list);
private:
bool empty() const { return size==0; }
Node* get_prev(const Node* node) const // for nodes in this list to get the previous
{
if(node == first || node == nullptr) // if it is the first node
return nullptr;
Node* temp = first;
while(temp != nullptr) // traverse until the end of the list is reached
{
if(temp->next == node) // if there is a node that has node as next in this list
return temp; // return that list
temp = temp->next;
}
return nullptr;
}
Node* first;
Node* last;
size_t size;
};
int main(void)
{
List<int> list;
list.push_back(1);
list.push_back(2);
list.push_back(3);
list.push_front(4);
list.push_front(5);
list.print();
list.pop_back();
list.pop_front();
list.print();
list.pop_back();
list.pop_front();
list.print();
if(list.pop_back() == false)
std::cout << "list was empty" << std::endl;
if(list.pop_front() == false)
std::cout << "list was empty" << std::endl;
list.print();
return 0;
}
|
Note: when popping the success is returned, so if the List was empty it returns false
Is everything clear up to here?
I added a few comments to follow my mind
edit: so, now let's merge them, right? :)
we should make an insert function for that task, but what parameter should it take?
Should you be able to insert after/before a specific node or should you insert your node at a position in the List?