Add chapter 2 and 4 labs for 2436 and database prog, respectively

This commit is contained in:
askiiart 2024-03-06 20:04:46 -06:00
parent 1f87bd00ad
commit f8b2dca3a3
Signed by untrusted user who does not match committer: askiiart
GPG key ID: BC3800E55FB54D67
18 changed files with 666 additions and 160 deletions

View file

@ -0,0 +1,61 @@
#ifndef NODE_H
#define NODE_H
class Node {
protected:
double data;
Node* next;
Node* previous;
public:
// Constructs this node with the specified numerical data value. The next
// and previous pointers are each assigned nullptr.
Node(double initialData) {
data = initialData;
next = nullptr;
previous = nullptr;
}
// Constructs this node with the specified numerical data value, next
// pointer, and previous pointer.
Node(double initialData, Node* nextNode, Node* previousNode) {
data = initialData;
next = nextNode;
previous = previousNode;
}
virtual ~Node() {
}
// Returns this node's data.
virtual double GetData() {
return data;
}
// Sets this node's data.
virtual void SetData(double newData) {
data = newData;
}
// Gets this node's next pointer.
virtual Node* GetNext() {
return next;
}
// Sets this node's next pointer.
virtual void SetNext(Node* newNext) {
next = newNext;
}
// Gets this node's previous pointer.
virtual Node* GetPrevious() {
return previous;
}
// Sets this node's previous pointer.
virtual void SetPrevious(Node* newPrevious) {
previous = newPrevious;
}
};
#endif

View file

@ -0,0 +1,68 @@
# 4.14 LAB: Sorted number list implementation with linked lists - C++
## Step 1: Inspect the Node.h file
Inspect the class declaration for a doubly-linked list node in Node.h. Access Node.h by clicking on the orange arrow next to main.cpp at the top of the coding window. The Node class has three member variables:
- a double data value,
- a pointer to the next node, and
- a pointer to the previous node.
Each member variable is protected. So code outside of the class must use the provided getter and setter member functions to get or set a member variable.
Node.h is read only, since no changes are required.
## Step 2: Implement the Insert() member function
A class for a sorted, doubly-linked list is declared in SortedNumberList.h. Implement the SortedNumberList class's Insert() member function. The function must create a new node with the parameter value, then insert the node into the proper sorted position in the linked list. Ex: Suppose a SortedNumberList's current list is `23 → 47.25 → 86`, then `Insert(33.5)` is called. A new node with data value 33.5 is created and inserted between 23 and 47.25, thus preserving the list's sorted order and yielding: `23 → 35.5 → 47.25 → 86`
## Step 3: Test in develop mode
Code in main() takes a space-separated list of numbers and inserts each into a SortedNumberList. The list is displayed after each insertion. Ex: If input is
```txt
77 15 -42 63.5
```
then output is:
```txt
List after inserting 77:
77
List after inserting 15:
15 77
List after inserting -42:
-42 15 77
List after inserting 63.5:
-42 15 63.5 77
```
Try various program inputs, ensuring that each outputs a sorted list.
## Step 4: Implement the Remove() member function
Implement the SortedNumberList class's Remove() member function. The function takes a parameter for the number to be removed from the list. If the number does not exist in the list, the list is not changed and false is returned. Otherwise, the first instance of the number is removed from the list and true is returned.
Uncomment the commented-out part in main() that reads a second input line and removes numbers from the list. Test in develop mode to ensure that insertion and removal both work properly, then submit code for grading. Ex: If input is
```txt
84 72 19 61
19 84
```
then output is:
```txt
List after inserting 84:
84
List after inserting 72:
72 84
List after inserting 19:
19 72 84
List after inserting 61:
19 61 72 84
List after removing 19:
61 72 84
List after removing 84:
61 72
```

View file

@ -0,0 +1,114 @@
#ifndef SORTEDNUMBERLIST_H
#define SORTEDNUMBERLIST_H
#include "Node.h"
class SortedNumberList {
private:
// Optional: Add any desired private functions here
/*
These traverse the list up/down from startingNode and updates the head/tail
Less efficient than just doing it in the functions based off the stuff there, but this is a bit easier on my brain
than dealing with edge cases there. Maybe the compiler can optimize it a bit, idk, I don't feel like digging
into the assembly (well, not right now)
Note: These used to be one function, UpdateHeadAndTail(), but I've split UpdateHead() and UpdateTail() into two
different functions in order to minimize the performance hit.
*/
void UpdateHead(Node *startingNode) {
Node *currentNode = startingNode;
while (currentNode->GetPrevious() != nullptr) {
currentNode = currentNode->GetPrevious();
}
head = currentNode;
}
void UpdateTail(Node *startingNode) {
Node *currentNode = startingNode;
while (currentNode->GetNext() != nullptr) {
currentNode = currentNode->GetNext();
}
tail = currentNode;
}
public:
Node *head;
Node *tail;
SortedNumberList() {
head = nullptr;
tail = nullptr;
}
// Inserts the number into the list in the correct position such that the
// list remains sorted in ascending order.
void Insert(double number) {
if (head == nullptr) { // handle being a new list with no data in it
// if (false) {
head = new Node(number);
tail = head;
}
else { // actually do anything interesting
Node *currentNode = head;
while (true) {
// needs debugging, if less than head, replaces head, if more, throws SIGSEGV (Address boundary error)
if (currentNode->GetData() <= number &&
(currentNode->GetNext() == nullptr || currentNode->GetNext()->GetData() <= number)) {
Node *newNode = new Node(number, currentNode->GetNext(), currentNode);
if (newNode->GetNext() != nullptr) {
currentNode->SetNext(newNode);
}
else {
head = newNode;
}
if (newNode->GetNext() != nullptr) {
newNode->GetNext()->SetPrevious(newNode);
}
else {
tail = newNode;
}
// I split these into 2 different functions so they *could* be more efficient,
// not so they *would* be more efficient :P
// UpdateHead(newNode);
// UpdateTail(newNode);
break;
}
currentNode = currentNode->GetNext();
}
}
}
// Removes the node with the specified number value from the list. Returns
// true if the node is found and removed, false otherwise.
bool Remove(double number) {
// deal with having an empty list
if (head == nullptr) {
return false;
}
else {
Node *currentNode = head;
while (currentNode != nullptr) {
if (currentNode->GetData() == number) {
// Change around the adjacent nodes to point to each other
// Gotta deal with being the start or ending node
// (next or prev being nullptr), though
if (currentNode->GetPrevious() != nullptr) {
currentNode->GetPrevious()->SetNext(currentNode->GetNext());
}
if (currentNode->GetNext() != nullptr) {
currentNode->GetNext()->SetPrevious(currentNode->GetPrevious());
}
UpdateHead(currentNode);
UpdateTail(currentNode);
return true;
}
currentNode = currentNode->GetNext();
}
return false;
}
}
};
#endif

View file

@ -0,0 +1,67 @@
#include <iostream>
#include <string>
#include <vector>
#include "Node.h"
#include "SortedNumberList.h"
using namespace std;
void PrintList(SortedNumberList& list);
vector<string> SpaceSplit(string source);
int main(int argc, char *argv[]) {
// Read the line of input numbers
string inputLine;
getline(cin, inputLine);
// Split on space character
vector<string> terms = SpaceSplit(inputLine);
// Insert each value and show the sorted list's contents after each insertion
SortedNumberList list;
for (auto term : terms) {
double number = stod(term);
list.Insert(number);
cout << "List after inserting " << number << ": " << endl;
PrintList(list);
}
/*
// Read the input line with numbers to remove
getline(cin, inputLine);
terms = SpaceSplit(inputLine);
// Remove each value
for (auto term : terms) {
double number = stod(term);
cout << "List after removing " << number << ": " << endl;
list.Remove(number);
PrintList(list);
}
*/
return 0;
}
// Prints the SortedNumberList's contents, in order from head to tail
void PrintList(SortedNumberList& list) {
Node* node = list.head;
while (node) {
cout << node->GetData() << " ";
node = node->GetNext();
}
cout << endl;
}
// Splits a string at each space character, adding each substring to the vector
vector<string> SpaceSplit(string source) {
vector<string> result;
size_t start = 0;
for (size_t i = 0; i < source.length(); i++) {
if (' ' == source[i]) {
result.push_back(source.substr(start, i - start));
start = i + 1;
}
}
result.push_back(source.substr(start));
return result;
}

View file

@ -0,0 +1,31 @@
class Node:
# Initializes this node with the specified numerical data value, next
# pointer, and previous pointer.
def __init__(self, initial_data, next_node=None, previous_node=None):
self.data = initial_data
self.next = next_node
self.previous = previous_node
# Returns this node's data.
def get_data(self):
return self.data
# Sets this node's data.
def set_data(self, new_data):
self.data = new_data
# Gets this node's next pointer.
def get_next(self):
return self.next
# Sets this node's next pointer.
def set_next(self, new_next):
self.next = new_next
# Gets this node's previous pointer.
def get_previous(self):
return self.previous
# Sets this node's previous pointer.
def set_previous(self, new_previous):
self.previous = new_previous

View file

@ -0,0 +1,78 @@
# 4.16 LAB: Sorted number list implementation with linked lists - Python
## Step 1: Inspect the Node.py file
Inspect the class declaration for a doubly-linked list node in Node.py. Access Node.py by clicking on the orange arrow next to main.py at the top of the coding window. The Node class has three attributes:
- a floating-point data value,
- a reference to the next node, and
- a reference to the previous node.
Node.py is read only, since no changes are required.
Step 2: Implement the insert() method
A class for a sorted, doubly-linked list is declared in SortedNumberList.py. Implement the SortedNumberList class's insert() method. The method must create a new node with the parameter value, then insert the node into the proper sorted position in the linked list. Ex: Suppose a SortedNumberList's current list is `23 → 47.25 → 86`, then `insert(33.5)` is called. A new node with data value 33.5 is created and inserted between 23 and 47.25, thus preserving the list's sorted order and yielding: `23 → 35.5 → 47.25 → 86`
## Step 3: Test in develop mode
Code in main() takes a space-separated list of numbers and inserts each into a SortedNumberList. The list is displayed after each insertion. Ex: If input is
```txt
77 15 -42 63.5
```
then output is:
```txt
List after inserting 77:
77
List after inserting 15:
15 77
List after inserting -42:
-42 15 77
List after inserting 63.5:
-42 15 63.5 77
```
Try various program inputs, ensuring that each outputs a sorted list.
## Step 4: Implement the remove() method
Implement the SortedNumberList class's remove() method. The method takes a parameter for the number to be removed from the list. If the number does not exist in the list, the list is not changed and false is returned. Otherwise, the first instance of the number is removed from the list and true is returned.
Uncomment the commented-out part in main() that reads a second input line and removes numbers from the list. Test in develop mode to ensure that insertion and removal both work properly, then submit code for grading.
Ex: If input is
```txt
84 72 19 61
19 84
```
then output is:
```txt
List after inserting 84:
84
List after inserting 72:
72 84
List after inserting 19:
19 72 84
List after inserting 61:
19 61 72 84
List after removing 19:
61 72 84
List after removing 84:
61 72
```
---
```txt
PASS: Inserting 25.5 yields ( 25.5 )
PASS: Inserting 75.75 yields ( 25.5, 75.75 )
PASS: Inserting 88.5 yields ( 25.5, 75.75, 88.5 )
FAIL: Insert 30:
Expected list: ( 25.5, 30, 75.75, 88.5 )
Actual list: ( 30, 75.75, 88.5 )
```

View file

@ -0,0 +1,63 @@
from Node import Node
class SortedNumberList:
def __init__(self):
self.head = None
self.tail = None
# Inserts the number into the list in the correct position such that the
# list remains sorted in ascending order.
def insert(self, number):
if self.head == None:
self.head = Node(number)
self.tail = self.head
else:
current_node = self.head
new_node = Node(number)
while True:
# handles most stuff
# probably got an error cuz this is confusing
if current_node != None and current_node.get_data() >= number:
new_node.set_next(current_node)
new_node.set_previous(current_node.get_previous())
if new_node.get_previous() != None:
new_node.get_previous().set_next(new_node)
else:
self.head = new_node
current_node.set_previous(new_node)
break
# handles being at the end
if current_node == None:
self.tail.set_next(new_node)
new_node.set_previous(self.tail)
self.tail = new_node
break
current_node = current_node.get_next()
# Removes the node with the specified number value from the list. Returns
# True if the node is found and removed, False otherwise.
def remove(self, number):
current_node = self.head
while True and current_node != None:
if current_node.get_data() == number:
next_node = current_node.get_next()
previous_node = current_node.get_previous()
if next_node != None:
next_node.set_previous(previous_node)
else:
self.tail = previous_node
if previous_node != None:
previous_node.set_next(next_node)
else:
self.head = next_node
return True
current_node = current_node.get_next()
return False

View file

@ -0,0 +1,35 @@
from SortedNumberList import SortedNumberList
def main():
# Read the line of input numbers
terms = input().split()
sorted_list = SortedNumberList()
# Insert each value and show the sorted list's contents after each insertion
for term in terms:
number = float(term)
print(f"""List after inserting {number}: """)
sorted_list.insert(number)
print_list(sorted_list)
# Read the input line with numbers to remove
terms = input().split()
for term in terms:
number = float(term)
print(f"""List after removing {number}: """)
sorted_list.remove(number)
print_list(sorted_list)
# Prints the sorted_number_list's contents, in order from head to tail
def print_list(lst):
node = lst.head
while node != None:
print(node.get_data(), end=' ')
node = node.get_next()
print()
if __name__ == '__main__':
main()