diff --git a/04-dl-lists/CMakeLists.txt b/04-dl-lists/CMakeLists.txt index 8c97fd2..1a1cfa0 100644 --- a/04-dl-lists/CMakeLists.txt +++ b/04-dl-lists/CMakeLists.txt @@ -6,4 +6,6 @@ set(CMAKE_CXX_STANDARD 20) add_executable(04_dl_lists main.cpp StudentList.cpp LinkedList.cpp - Park.cpp) + Park.cpp + ListNodeADT.h + LinkedListADT.h) diff --git a/04-dl-lists/LinkedListADT.h b/04-dl-lists/LinkedListADT.h new file mode 100644 index 0000000..0936593 --- /dev/null +++ b/04-dl-lists/LinkedListADT.h @@ -0,0 +1,219 @@ +// Specification file for the LinkedList class +// Written By: Iurii Tatishchev +// Reviewed & Modified by: Iurii Tatishchev +// IDE: CLion + +#ifndef LINKED_LIST_H +#define LINKED_LIST_H + +#include "ListNodeADT.h" + +template +class LinkedList { +private: + ListNode *head; + int length; + +public: + LinkedList(); // constructor + ~LinkedList(); // destructor + + // Linked list operations + int getLength() const { return length; } + + bool isEmpty() const { return length == 0; } + + void insertNode(const T &); + + bool deleteNode(const T &); + + void displayListForw() const; + + void displayListBack() const; + + bool searchList(const T &, T &) const; +}; + +// ************************************************** +// Constructor +// This function allocates and initializes a sentinel node +// A sentinel (or dummy) node is an extra node added before the first data record. +// This convention simplifies and accelerates some list-manipulation algorithms, +// by making sure that all links can be safely dereferenced and that every list +// (even one that contains no data elements) always has a "first" node. +// ************************************************** +template +LinkedList::LinkedList() { + head = new ListNode; // head points to the sentinel node + head->setNext(head); + head->setPrev(head); + length = 0; +} + +// ************************************************** +// The insertNode function inserts a new node in a +// sorted linked list +// ************************************************** +template +void LinkedList::insertNode(const T &dataIn) { + ListNode *newNode; // A new node + ListNode *pCur; // To traverse the list + ListNode *pPre; // The previous node + + // Allocate a new node and store dataIn there. + newNode = new ListNode(dataIn); + + // Initialize pointers + pCur = head->getNext(); + + // Find location: skip all nodes whose code is less than dataIn's code + // while (pCur != head && newNode->getData().getCode() > pCur->getData().getCode()) + while (pCur != head && newNode->getData() > pCur->getData()) { + pCur = pCur->getNext(); + } + + // Insert the new node between pPre and pCur + pPre = pCur->getPrev(); + pPre->setNext(newNode); + newNode->setNext(pCur); + newNode->setPrev(pPre); + pCur->setPrev(newNode); + + // Update the counter + length++; +} + +// ************************************************** +// The deleteNode function searches for a node +// in a sorted linked list; if found, the node is +// deleted from the list and from memory. +// ************************************************** +//bool LinkedList::deleteNode(string target) +template +bool LinkedList::deleteNode(const T &target) { + ListNode *pCur; // To traverse the list + ListNode *pPre; // To point to the previous node + bool deleted = false; + + // Initialize pointers + pCur = head->getNext(); + + // Find node containing the target: Skip all nodes whose gpa is less than the target + while (pCur != head && pCur->getData() < target) { + pCur = pCur->getNext(); + } + + // If found, delete the node + if (pCur->getData() == target) { + pPre = pCur->getPrev(); + pPre->setNext(pCur->getNext()); // Set next of prev + pCur->getNext()->setPrev(pPre); // Set prev of next + + delete pCur; + deleted = true; + length--; + } + + return deleted; +} + +// ************************************************** +// displayList shows the value +// stored in each node of the linked list +// pointed to by head, except the sentinel node +// ************************************************** +template +void LinkedList::displayListForw() const { + ListNode *pCur; // To move through the list + + // Position pCur: skip the head of the list. + pCur = head->getNext(); + + // While pCur points to a node, traverse the list. + while (pCur != head) { + // Display the value in this node. + std::cout << pCur->getData(); + + // Move to the next node. + pCur = pCur->getNext(); + } + std::cout << std::endl; +} + +// ************************************************** +// displayList shows the value +// stored in each node of the linked list +// pointed to by head, except the sentinel node +// ************************************************** +template +void LinkedList::displayListBack() const { + ListNode *pCur; // To move through the list + + // Position pCur: skip the head of the list. + pCur = head->getPrev(); + + // While pCur points to a node, traverse the list. + while (pCur != head) { + // Display the value in this node. + std::cout << pCur->getData(); + + // Move to the next node. + pCur = pCur->getPrev(); + } + std::cout << std::endl; +} + + +// ************************************************** +// The searchList function looks for a target college +// in the sorted linked list: if found, returns true +// and copies the data in that node to the output parameter +// ************************************************** +template +bool LinkedList::searchList(const T &target, T &dataOut) const { + bool found = false; // assume target not found + ListNode *pCur; // To move through the list + + // Position pCur: skip the head of the list. + pCur = head->getNext(); + // Find location: skip all nodes whose code is less than target + while (pCur != head && pCur->getData() < target) { + pCur = pCur->getNext(); + } + + // If found, copy data to the output parameter, and change the flag to true + if (pCur != head && pCur->getData() == target) { + dataOut = pCur->getData(); + found = true; + } + + return found; +} + +// ************************************************** +// Destructor +// This function deletes every node in the list. +// ************************************************** +template +LinkedList::~LinkedList() { + ListNode *pCur; // To traverse the list + ListNode *pNext; // To hold the address of the next node + + // Position nodePtr: skip the head of the list + pCur = head->getNext(); + // While pCur is not at the end of the list... + while (pCur != head) { + // Save a pointer to the next node. + pNext = pCur->getNext(); + + // Delete the current node. + delete pCur; + + // Position pCur at the next node. + pCur = pNext; + } + + delete head; // delete the sentinel node +} + +#endif diff --git a/04-dl-lists/ListNodeADT.h b/04-dl-lists/ListNodeADT.h new file mode 100644 index 0000000..a9b9e65 --- /dev/null +++ b/04-dl-lists/ListNodeADT.h @@ -0,0 +1,47 @@ +// Specification file for the ListNode class +// Written by: Iurii Tatishchev +// Reviewed & Modified by: Iurii Tatishchev +// IDE: CLion + +#ifndef LISTNODE_H +#define LISTNODE_H + +#include +// #include "Park.h" +// ^^^ not included here anymore + +template +class ListNode { +private: + T data; // store data + ListNode *forw; // a pointer to the next node in the list + ListNode *back; // a pointer to the previous node in the list +public: + //Constructor + ListNode() { forw = back = nullptr; } + + ListNode(const T &dataIn, ListNode *forw = nullptr, ListNode *back = nullptr) { + data = dataIn; + this->forw = forw; + this->back = back; + } + + // setters + // set the data + void setData(const T &dataIn) { data = dataIn; } + // set the forw pointer + void setNext(ListNode *nextPtr) { forw = nextPtr; } + // set the back pointer + void setPrev(ListNode *prevPtr) { back = prevPtr; } + + // getters + // return data object in the listnode + T& getData() { return data; } + // return pointer in the next node + ListNode *getNext() const { return forw; } + // return pointer in the previous node + ListNode *getPrev() const { return back; } + +}; + +#endif diff --git a/04-dl-lists/Park.cpp b/04-dl-lists/Park.cpp index 7c32cf9..c00b59c 100644 --- a/04-dl-lists/Park.cpp +++ b/04-dl-lists/Park.cpp @@ -3,9 +3,7 @@ // Reviewed By: Iurii Tatishchev // IDE: CLion - #include -#include #include #include "Park.h" @@ -56,5 +54,16 @@ void Park::vDisplay() const { cout << description << endl; cout << state << endl; cout << year << endl; + } +/* overloaded operators + * - the stream insertion operator ( << ) based on hDisplay + */ +ostream &operator<<(ostream &out, const Park &park) { + out << park.code << " "; + out << park.state << " "; + out << park.year << " "; + out << park.name << " \n"; + return out; +} diff --git a/04-dl-lists/Park.h b/04-dl-lists/Park.h index 3cdcf7c..ce4aaaf 100644 --- a/04-dl-lists/Park.h +++ b/04-dl-lists/Park.h @@ -59,6 +59,18 @@ public: void hDdisplay() const; void vDisplay() const; + + /* overloaded operators + - the stream insertion operator ( << ) + - the relational operators (<, >, == ) + */ + friend std::ostream &operator<<(std::ostream &out, const Park &park); + + bool operator<(const Park &park) const { return code < park.code; } + + bool operator>(const Park &park) const { return code > park.code; } + + bool operator==(const Park &park) const { return code == park.code; } }; #endif diff --git a/04-dl-lists/main.cpp b/04-dl-lists/main.cpp index ff4d0d7..cc85515 100644 --- a/04-dl-lists/main.cpp +++ b/04-dl-lists/main.cpp @@ -1,35 +1,40 @@ /* - Sorted Circular Doubly-Linked List with Sentinel Node + CIS 22C: Homework 4 + + Sorted Circular Doubly-Linked List ADT with Sentinel Node Build and procees a sorted linked list of Park objects. The list is sorted in ascending order by the Park code, a unique identifier. +*/ + // Written by: Iurii Tatishchev // Reviewed & Modified by: Iurii Tatishchev // IDE: CLion - */ - #include #include #include #include #include // toupper() -#include "LinkedList.h" + +#include "LinkedListADT.h" +#include "Park.h" using namespace std; -void buildList(const string &filename, LinkedList &list); +void buildList(const string &filename, LinkedList &list); -void deleteManager(LinkedList &list); +void deleteManager(LinkedList &list); -void searchManager(const LinkedList &list); +void searchManager(const LinkedList &list); -void displayManager(const LinkedList &list); +void displayManager(const LinkedList &list); int main() { + string inputFileName = "national_parks.txt"; - LinkedList list; + LinkedList list; buildList(inputFileName, list); displayManager(list); @@ -43,7 +48,7 @@ int main() { This function reads data about national parks from a file and inserts them into a sorted linked list. The list is sorted in ascending order by code. */ -void buildList(const string &filename, LinkedList &list) { +void buildList(const string &filename, LinkedList &list) { ifstream inputFile(filename); cout << "Reading data from \"" << filename << "\"" << endl; @@ -76,9 +81,9 @@ void buildList(const string &filename, LinkedList &list) { /* Delete manager: delete items from the list until the user enters Q to quit deleting - Input Parameter: list + Input & Output Parameter: list */ -void deleteManager(LinkedList &list) { +void deleteManager(LinkedList &list) { string targetCode; cout << endl << " Delete" << endl; @@ -89,7 +94,9 @@ void deleteManager(LinkedList &list) { getline(cin, targetCode); targetCode[0] = toupper(targetCode[0]); if (targetCode != "Q") { - if (list.deleteNode(targetCode)) + Park target; + target.setCode(targetCode); + if (list.deleteNode(target)) cout << " " << targetCode << " has been deleted!" << endl; else cout << "Park \"" << targetCode << "\" was not found in this list." << endl; @@ -102,7 +109,7 @@ void deleteManager(LinkedList &list) { Search manager: search the list until the user enters Q to quit searching Input Parameter: list */ -void searchManager(const LinkedList &list) { +void searchManager(const LinkedList &list) { string targetCode = ""; Park aPark; @@ -114,7 +121,9 @@ void searchManager(const LinkedList &list) { getline(cin, targetCode); targetCode[0] = toupper(targetCode[0]); if (targetCode != "Q") { - if (list.searchList(targetCode, aPark)) + Park target; + target.setCode(targetCode); + if (list.searchList(target, aPark)) aPark.vDisplay(); else cout << "Park \"" << targetCode << "\" was not found in this list." << endl; @@ -129,7 +138,7 @@ Display manager: - calls the displayListForw()/displayListBack() function upon request Input Parameter: list */ -void displayManager(const LinkedList &list) { +void displayManager(const LinkedList &list) { string action; cout << "Number of National Parks in this list: " << list.getLength() << endl;