#include using namespace std; namespace std { string to_string(string s){ return s; } } template class linked_list { struct llnode { T data; llnode *next = 0; }; llnode *start = 0; llnode *last = 0; class lliterator { llnode *place; public: lliterator(llnode *p) : place(p) {} lliterator& operator++() { place = place->next; return *this; } bool operator!=(const lliterator& other) const { return place != other.place; } T& operator*(){ return place->data; } }; public: // O(1) void push_back(const T& new_item){ if(start == 0) { start = new llnode; start->data = new_item; last = start; return; } // Now place points to the last item in the list last->next = new llnode; last = last->next; last->data = new_item; } // It'll print out like this: // [one, two, three] // also O(n) string to_string() const { llnode *place = start; string output = "["; while(place){ output += std::to_string(place->data); if(place->next) output += ", "; place = place->next; } output += "]"; return output; } // This one is O(n) ~linked_list(){ llnode *place = start; while(place){ llnode *todelete = place; place = place->next; delete todelete; } } // O(n) // Candidate for exception handling? T& operator[](size_t index){ llnode *place = start; while(index > 0){ index--; place = place->next; } return place->data; } // O(n) where n is index void insert(const T& new_item, size_t index){ llnode *new_node = new llnode; new_node->data = new_item; if(index == 0){ new_node->next = start; start = new_node; if(!last) last = start; return; } llnode *place = start; while(index > 1){ index--; place = place->next; } new_node->next = place->next; place->next = new_node; if(place == last) last = place; } // O(1) void push(const T& new_item){ insert(new_item, 0); } // O(1) bool empty(){ return !start; } // O(1) T pop(){ T retval = start->data; llnode *todel = start; if(start == last) last = 0; start = start->next; delete todel; return retval; } // O(1) lliterator begin(){ return lliterator(start); } // O(1) lliterator end(){ return lliterator(0); } // O(1) void enqueue(const T& new_item){ push_back(new_item); } // O(1) T dequeue(){ return pop(); } }; template ostream& operator<<(ostream& out, const linked_list& ll){ return out << ll.to_string(); } int main(){ linked_list animal_stack; animal_stack.push("Emu"); animal_stack.push("Fish"); animal_stack.push("Gorilla"); animal_stack.push("Horse"); animal_stack.push("Iguana"); cout << "animal_stack: " << animal_stack << endl; cout << "Popping animals off the stack: \n"; while(!animal_stack.empty()) cout << animal_stack.pop() << endl; linked_list number_queue; number_queue.enqueue(3); number_queue.enqueue(6); number_queue.enqueue(9); number_queue.enqueue(12); number_queue.enqueue(15); cout << number_queue << endl; cout << "Dequeuing numbers: \n"; while(!number_queue.empty()) cout << number_queue.dequeue() << endl; return 0; }