6.23 Lab*: Doubly-Linked Lists (Park) - Templates
This commit is contained in:
parent
274e3025b1
commit
ef6762ad57
@ -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)
|
||||
|
219
04-dl-lists/LinkedListADT.h
Normal file
219
04-dl-lists/LinkedListADT.h
Normal file
@ -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 T>
|
||||
class LinkedList {
|
||||
private:
|
||||
ListNode<T> *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<class T>
|
||||
LinkedList<T>::LinkedList() {
|
||||
head = new ListNode<T>; // 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<class T>
|
||||
void LinkedList<T>::insertNode(const T &dataIn) {
|
||||
ListNode<T> *newNode; // A new node
|
||||
ListNode<T> *pCur; // To traverse the list
|
||||
ListNode<T> *pPre; // The previous node
|
||||
|
||||
// Allocate a new node and store dataIn there.
|
||||
newNode = new ListNode<T>(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<class T>
|
||||
bool LinkedList<T>::deleteNode(const T &target) {
|
||||
ListNode<T> *pCur; // To traverse the list
|
||||
ListNode<T> *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<class T>
|
||||
void LinkedList<T>::displayListForw() const {
|
||||
ListNode<T> *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<class T>
|
||||
void LinkedList<T>::displayListBack() const {
|
||||
ListNode<T> *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<class T>
|
||||
bool LinkedList<T>::searchList(const T &target, T &dataOut) const {
|
||||
bool found = false; // assume target not found
|
||||
ListNode<T> *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<class T>
|
||||
LinkedList<T>::~LinkedList() {
|
||||
ListNode<T> *pCur; // To traverse the list
|
||||
ListNode<T> *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
|
47
04-dl-lists/ListNodeADT.h
Normal file
47
04-dl-lists/ListNodeADT.h
Normal file
@ -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 <iostream>
|
||||
// #include "Park.h"
|
||||
// ^^^ not included here anymore
|
||||
|
||||
template<class T>
|
||||
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
|
@ -3,9 +3,7 @@
|
||||
// Reviewed By: Iurii Tatishchev
|
||||
// IDE: CLion
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cctype> // 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<Park> &list);
|
||||
|
||||
void deleteManager(LinkedList &list);
|
||||
void deleteManager(LinkedList<Park> &list);
|
||||
|
||||
void searchManager(const LinkedList &list);
|
||||
void searchManager(const LinkedList<Park> &list);
|
||||
|
||||
void displayManager(const LinkedList &list);
|
||||
void displayManager(const LinkedList<Park> &list);
|
||||
|
||||
int main() {
|
||||
|
||||
string inputFileName = "national_parks.txt";
|
||||
LinkedList list;
|
||||
LinkedList<Park> 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<Park> &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<Park> &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<Park> &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<Park> &list) {
|
||||
string action;
|
||||
|
||||
cout << "Number of National Parks in this list: " << list.getLength() << endl;
|
||||
|
Loading…
x
Reference in New Issue
Block a user