Your destructor looks good.
insert() isn't right:
- Can't insert at the head of the list
- Won't modify
tail
if inserting at the end of the list.
Comment your code. Does insert() put the new item before or after then idx'th item? If you want to be able to insert at the head, then it needs to insert
before idx.
Line 86: You should never use "l" as a variable name. It's too easy to confuse to 1.
Linked lists can be simplified in C++ with the use of references and the
&
(address of) operator. Start with a generalized method to insert into the list:
1 2 3 4 5 6 7 8 9 10
|
// Given a value in a reference to "head" or a node's "next" pointer,
// insert a new node with the value before the one that headOrNext points to.
void insertBefore (T value, node * &headOrNext) {
node *newNode = new node(value);
newNode->next = headOrNext;
headOrNext = newNode;
if (tail == nullptr || &tail->next == &headOrNext) {
tail = newNode;
}
}
| |
Now push_back() and push_front() become trivial:
1 2 3 4 5 6 7 8 9 10 11
|
void push_back(T value) {
if (tail) {
insertBefore(value, tail->next);
} else {
insertBefore(value, head);
}
}
void push_front(T value){
insertBefore(value, head);
}
| |
insert() is a little harder, but only a little, The trick is to use a pointer to the head or next pointer.
1 2 3 4 5 6 7
|
void insert(T value, int idx)
{
node **pp;
for (pp = &head; idx--; pp = &(*pp)->next)
;
insertBefore(value, *pp);
}
| |
remove() would be just as simple, except for that damn tail pointer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
void remove(int idx)
{
if (idx == 0) {
node *tmp = head;
if (head == tail) tail = nullptr;
head = head->next;
delete tmp;
return;
}
node *prev;
for (prev = head; --idx; prev = prev->next)
;
node *tmp = prev->next; // tmp is the node to delete
prev->next = tmp->next;
if (tail == tmp) {
tail = prev;
}
delete tmp;
}
| |