Coding Exercise
Note
If you have not configured you repository yet, please refer to this guide. You have to set it up in order to test your solutions.
Retrieving The New Problem Set¶
Please run
1 | ./update |
To ensure you have the latest problem set. You should be able to see 3-singly-linked-list
and 4-std-list
in your repository.
Singly Linked List¶
The Code¶
This week's exercise will focus on lists. Specifically, you will be implementing singly linked list functions within 3-singly-linked-list
.
The 3-singly-linked-list
codebase consists of a partially complete singly linked list class. You will be filling in the empty functions in include/singly_linked_list.h
in order complete this exercise.
Warning
In your repository, please only modify the highlighted regions in include/singly_linked_list.h
indicated below
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 146 147 148 | #ifndef SINGLY_LINKED_LIST_H #define SINGLY_LINKED_LIST_H #include <stdexcept> using namespace std; template <typename T> struct Node { T data; Node<T> *next; Node() = delete; // No default constructor Node(const T &element) : data(element), next( nullptr ) {} }; template <typename T> class SinglyLinkedList { private: Node<T>* head; Node<T>* tail; public: SinglyLinkedList(); ~SinglyLinkedList(); bool empty(); void prepend(const T&); void append(const T&); void pop_front(); T& front(); T& back(); void clear(); size_t size(); T& at(size_t); void swap_head_tail(); }; template <typename T> void SinglyLinkedList<T>::clear() { // Delete every node in the linked list. // Utilize stdexcept to handle edge cases. // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> size_t SinglyLinkedList<T>::size() { // Return the number of nodes in the linked list. // Utilize stdexcept to handle edge cases. // ========= ONLY MODIFY BETWEEN THE LINES =========== return 0; // ==================================================== } template <typename T> T& SinglyLinkedList<T>::at(size_t i) { // Return the data stored in the ith node // Utilize stdexcept to handle edge cases. // ========= ONLY MODIFY BETWEEN THE LINES =========== return front(); // ==================================================== } template <typename T> void SinglyLinkedList<T>::swap_head_tail() { // Swap the head and tail nodes in the linked list. // Utilize stdexcept to handle edge cases. // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> SinglyLinkedList<T>::SinglyLinkedList() : head(nullptr), tail(nullptr) {} template <typename T> SinglyLinkedList<T>::~SinglyLinkedList() { clear(); } template <typename T> bool SinglyLinkedList<T>::empty() { return head == nullptr; } template <typename T> void SinglyLinkedList<T>::append(const T& newData) { Node<T> *newNode = new Node<T>(newData); // create new node if (head == nullptr) { // List empty head = newNode; tail = newNode; } else{ tail->next = newNode; tail = newNode; } } template <typename T> void SinglyLinkedList<T>::prepend(const T& newData) { Node<T> *newNode = new Node<T>(newData); // create new node if (head == nullptr) { // list empty head = newNode; tail = newNode; } else { newNode->next = head; head = newNode; } } template <typename T> void SinglyLinkedList<T>::pop_front() { if (empty()) throw length_error("empty list"); Node<T> *temp = head; head = head->next; delete temp; if (head == nullptr) tail = nullptr; } template <typename T> T& SinglyLinkedList<T>::front() { if(empty()) throw std::length_error( "empty list" ); return head->data; } template <typename T> T& SinglyLinkedList<T>::back() { if(empty()) throw std::length_error( "empty list" ); return tail->data; } #endif |
Testing¶
After you have modified your code, test it! You can test it by running
1 | ./run 3-singly-linked-list |
At the root of your repository.
If you've successfully implemented all of the functions, your output should look like this:
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 | ❯ ./run 3-singly-linked-list ============================================================================================== COMPILING 3-singly-linked-list TESTS ar: creating archive libgtest.a a - gtest-all.o ar: creating archive libgtest_main.a a - gtest-all.o a - gtest_main.o ============================================================================================== RUNNING 3-singly-linked-list TESTS unit_test_3 Running main() from /Users/oscar/Documents/projects/si-spring-2019/googletest/src/gtest_main.cc [==========] Running 4 tests from 1 test case. [----------] Global test environment set-up. [----------] 4 tests from Singly_Linked_List [ RUN ] Singly_Linked_List.Clear [ OK ] Singly_Linked_List.Clear (0 ms) [ RUN ] Singly_Linked_List.Size [ OK ] Singly_Linked_List.Size (0 ms) [ RUN ] Singly_Linked_List.At [ OK ] Singly_Linked_List.At (0 ms) [ RUN ] Singly_Linked_List.Swap_Head_And_Tail_Nodes [ OK ] Singly_Linked_List.Swap_Head_And_Tail_Nodes (0 ms) [----------] 4 tests from Singly_Linked_List (0 ms total) [----------] Global test environment tear-down [==========] 4 tests from 1 test case ran. (0 ms total) [ PASSED ] 4 tests. ============================================================================================== CLEANING 3-singly-linked-list UP ============================================================================================== |
STD List¶
The Code¶
In addition to the singly linked list implementation, we will also be leveraging the STL's implementation of a singly linked list. It is called a forward list. You will be performing operations on a forward list.
The 4-std-list
codebase consists of a incomplete functions that manipulate the forward list main_list
. You will be filling in the empty functions in include/lists.h
in order complete this exercise.
Warning
In your repository, please only modify the highlighted regions in include/lists.h
indicated below
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 | #ifndef LISTS #define LISTS #include <list> #include <algorithm> using namespace std; template <typename T> class ListQuestions { private: list<T> main_list; public: ListQuestions(list<T>); list<T>& get_list(); void push_front_elements(); void pop_front_elements(); void delete_element(); typename list<T>::iterator get_element(const T &); T sum(); void swap_elements(); void insert_elements(const T &); void sort(); void clear_elements(); }; // For the following tasks manipulate main_list. template <typename T> void ListQuestions<T>::push_front_elements() { // Insert 3 elements at the front of the list // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> void ListQuestions<T>::delete_element() { // Delete the third element from the front of the list // Example: // BEFORE: [ 1 2 4 6 1 4 . . . ] // ^ // AFTER: [ 1 2 6 1 4 . . . ] typename list<T>::iterator it = main_list.begin(); // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> typename list<T>::iterator ListQuestions<T>::get_element(const T &elem) { // Retreive an element from the list. Retrieve the element using an iterator. // Hint: utilize std::algorithm typename list<T>::iterator it = main_list.begin(); // ========= ONLY MODIFY BETWEEN THE LINES =========== return it; // ==================================================== } template <typename T> void ListQuestions<T>::pop_front_elements() { // Remove 3 elements at the front of the list // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> T ListQuestions<T>::sum() { // Find the sum of all of the elements of the list. Utilize iterators. typename list<T>::iterator it = main_list.begin(); // ========= ONLY MODIFY BETWEEN THE LINES =========== return *it; // ==================================================== } template <typename T> void ListQuestions<T>::swap_elements() { // Swap the first and the last element in the list. Utilize iterators. // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> void ListQuestions<T>::insert_elements(const T &elem) { // Insert an element at the 3rd position in the list. // Example: // BEFORE: [ 1 2 4 6 1 4 . . . ] // ^ // AFTER: [ 1 2 n 4 6 1 4 . . . ] typename list<T>::iterator it = main_list.begin(); // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> void ListQuestions<T>::sort() { // Sort the elements in the list in ascending order. // Hint: Use std::algorithm // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> void ListQuestions<T>::clear_elements() { // Remove every element from the list. // ========= ONLY MODIFY BETWEEN THE LINES =========== return; // ==================================================== } template <typename T> ListQuestions<T>::ListQuestions(list<T> copy_list) { for (T i : copy_list) main_list.push_back(i); } template <typename T> list<T>& ListQuestions<T>::get_list() { return main_list; } #endif |
Testing¶
After you have modified your code, test it! You can test it by running
1 | ./run 4-std-list |
At the root of your repository.
If you've successfully implemented all of the functions, your output should look like this:
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 | ❯ ./run 4-std-list ============================================================================================ COMPILING 4-std-list TESTS ar: creating archive libgtest.a a - gtest-all.o ar: creating archive libgtest_main.a a - gtest-all.o a - gtest_main.o ============================================================================================ RUNNING 4-std-list TESTS unit_test_4 Running main() from /Users/oscar/Documents/projects/si-spring-2019/googletest/src/gtest_main.cc [==========] Running 9 tests from 1 test case. [----------] Global test environment set-up. [----------] 9 tests from [ RUN ] .Push_Front [ OK ] .Push_Front (0 ms) [ RUN ] .Delete_Element [ OK ] .Delete_Element (0 ms) [ RUN ] .Get_Element [ OK ] .Get_Element (0 ms) [ RUN ] .Pop_Front [ OK ] .Pop_Front (0 ms) [ RUN ] .Sum [ OK ] .Sum (0 ms) [ RUN ] .Swap [ OK ] .Swap (0 ms) [ RUN ] .Insert_Elements [ OK ] .Insert_Elements (0 ms) [ RUN ] .Sort [ OK ] .Sort (0 ms) [ RUN ] .Clear [ OK ] .Clear (0 ms) [----------] 9 tests from (0 ms total) [----------] Global test environment tear-down [==========] 9 tests from 1 test case ran. (1 ms total) [ PASSED ] 9 tests. ============================================================================================ CLEANING 4-std-list UP ============================================================================================ |