#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; 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(n) void push_back(const T& new_item){ if(start == 0) { start = new llnode; start->data = new_item; return; } // Traverse the list to find the end (this part is O(n) ) llnode *place = start; while(place->next){ place = place->next; } // Now place points to the last item in the list place->next = new llnode; place->next->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; return; } llnode *place = start; while(index > 1){ index--; place = place->next; } new_node->next = place->next; place->next = new_node; } // O(1) void push(const T& new_item){ insert(new_item, 0); } bool empty(){ return !start; } // O(1) T pop(){ T retval = start->data; llnode *todel = start; start = start->next; delete todel; return retval; } // O(1) lliterator begin(){ return lliterator(start); } // O(1) lliterator end(){ return lliterator(0); } }; template ostream& operator<<(ostream& out, const linked_list& ll){ return out << ll.to_string(); } int main(){ linked_list test; test.push_back(4.13); test.push_back(32.14); test.push_back(8.4567); test.push_back(2.71); test.push_back(1.41); cout << test << endl; // Don't do this! // test[i] is O(n) // Loop runs once per item // O(n^2) /* for(int i = 0; i < 5; i++) cout << "Item: " << test[i] << endl; */ // These are O(n) instead for(auto item : test) cout << "Item: " << item << endl; for(auto &item : test) item *= 3; cout << "Tripled: " << test << endl; cout << test[2] << endl; test[3] = 123.456; test.insert(7.777, 0); test.insert(2.132, 2); cout << test << endl; test.push(1.0000); cout << test << endl; cout << "pop! " << test.pop() << endl; cout << "pop! " << test.pop() << endl; cout << "pop! " << test.pop() << endl; cout << test << endl; while(!test.empty()) cout << "pop! " << test.pop() << endl; cout << test << endl; linked_list string_test; string_test.push("dugong"); string_test.push("moose"); string_test.push("elephant"); cout << string_test << endl; return 0; }