diff --git a/src/lib/Graph/Graph.ts b/src/lib/Graph/index.ts similarity index 100% rename from src/lib/Graph/Graph.ts rename to src/lib/Graph/index.ts diff --git a/src/lib/LinkedList/ListNode.ts b/src/lib/LinkedList/ListNode.ts index e81a075..1cdd4db 100644 --- a/src/lib/LinkedList/ListNode.ts +++ b/src/lib/LinkedList/ListNode.ts @@ -14,6 +14,10 @@ export default class ListNode extends Node { this.next = node; } + setPreviousNode(node: ListNode) { + this.prev = node; + } + get nextNode() { return this.next; } diff --git a/src/lib/LinkedList/index.ts b/src/lib/LinkedList/index.ts new file mode 100644 index 0000000..dcb5405 --- /dev/null +++ b/src/lib/LinkedList/index.ts @@ -0,0 +1,180 @@ +import ListNode from "./ListNode"; + +export default class LinkedList { + private head: ListNode | null + private tail: ListNode | null + + constructor(head?: ListNode, tail?: ListNode) { + this.head = head || null; + this.tail = tail || null; + } + + getHead() { + return this.head; + } + + getTail() { + return this.tail; + } + + exchange(prev: ListNode, next: ListNode) { + prev.setNextNode(next); + next.setPreviousNode(prev); + } + + addToHead(data: T) { + // create a new node for the data to insert, and store the current head + const newHead = new ListNode(data); + const current = this.head; + + // swap the positions of these elements if current head is defined + if (current) this.exchange(current, newHead); + + // assign the new head in the class instance + this.head = newHead; + + // if there is no tail after this change, additionally assign the new head as the new tail + if (!this.tail) this.tail = newHead; + } + + addManyToHead(...items: T[]) { + for (let each of items) { + this.addToHead(each); + } + } + + // inverse of the logic above + addToTail(data: T) { + const newTail = new ListNode(data); + const current = this.tail; + + if (current) this.exchange(current, newTail); + + this.tail = newTail; + if (!this.head) this.head = newTail; + } + + removeHead(): T | null { + const toRemove = this.head; + + // if there's nothing to remove, don't remove it + if (!toRemove) return null; + + const newHead = toRemove.nextNode; + this.head = newHead; + + if (toRemove == this.tail) { + this.removeTail(); + } + + return toRemove.data as T; + } + + removeTail(): T | null { + const toRemove = this.tail; + if (!toRemove) return null; + + const newTail = toRemove.nextNode; + this.tail = newTail; + + if (toRemove == this.head) { + this.removeHead(); + } + + return toRemove.data as T; + } + + findByNode(node: ListNode): ListNode | null { + let current = this.head; + while (current !== null) { + if (current === node) { + return current; + } + + current = current.nextNode; + } + + return null; + } + + findByData(data: T): ListNode | null { + let current = this.head; + while (current !== null) { + if (current.data === data) { + return current; + } + + current = current.nextNode; + } + + return null; + } + + removeByData(data: T): ListNode | null { + let targetNode: ListNode | null = null; + let current = this.head; + while (current !== null) { + if (current.data == data) { + targetNode = current; + break; + } + + current = current.nextNode; + } + + if (!targetNode) return null; + + // by asserting above that target node is neither undefined, nor the head, + // nor the tail of the list, we can assert that next and prev will both be + // defined, as targetNode must be somewhere in the middle of the list + if (targetNode === this.head) { + this.removeHead(); + } else if (targetNode === this.tail) { + this.removeTail(); + } else { + // the method below effectively cuts the target node out of the list by assigning + // is surrounding members to fill in the space previously taken up by target node + const next = targetNode.nextNode; + const prev = targetNode.prevNode; + this.exchange(prev!, next!); + } + + return targetNode; + } + + removeAtPosition(pos: number): ListNode | null { + let targetNode: ListNode | null = null; + let current = this.head; + let i = 0; + + // traverse the list until you reach the end or the desired position, + // whichever happens first + while (current !== null) { + if (i == pos) { + targetNode = current; + break; + } + current = current.nextNode; + i++; + } + + // if you arrive at the end of the list without reaching the desired position, + // the removal operation was unsuccessful (no element at this position) + if (!targetNode && (i < pos)) { + console.log("No element found at position " + pos); + return null; + } + + if (targetNode === this.head) { + this.removeHead(); + } else if (targetNode === this.tail) { + this.removeTail(); + } else { + let next = targetNode?.nextNode; + let prev = targetNode?.prevNode; + this.exchange(prev!, next!); + } + + return targetNode; + } +} \ No newline at end of file diff --git a/src/lib/helpers/sample.ts b/src/lib/helpers/sample.ts index 2537574..1b03c34 100644 --- a/src/lib/helpers/sample.ts +++ b/src/lib/helpers/sample.ts @@ -1,9 +1,7 @@ -import Event from "../Event"; -import Graph from "../Graph/Graph"; -import GraphNode from "../Graph/GraphNode"; import { ChordQuality, EventData } from "./index"; +import LinkedList from "../LinkedList/index"; -const initialData: EventData = { +const firstEvent: EventData = { root: "C", quality: ChordQuality.Major, duration: 4, @@ -17,17 +15,19 @@ const secondEvent: EventData = { beatStrength: "Strong" } -const sampleEvent = new Event(initialData); -const nextEvent = new Event(secondEvent); -const third = new Event(initialData); -const fourth = new Event(secondEvent); +const thirdEvent: EventData = { + root: "F", + quality: ChordQuality.Major, + duration: 4, + beatStrength: "Strong" +} -third.setNextNode(fourth); -nextEvent.setNextNode(third); -sampleEvent.setNextNode(nextEvent); - -console.log(sampleEvent.getEventData()); -console.log(sampleEvent.nextNode); +const fourthEvent: EventData = { + root: "F", + quality: ChordQuality.Minor, + duration: 4, + beatStrength: "Strong" +} /*************** *************** @@ -40,14 +40,9 @@ console.log(sampleEvent.nextNode); *************** ***************/ +const eventlist = new LinkedList(); +eventlist.addManyToHead(firstEvent, secondEvent, thirdEvent, fourthEvent); -const sampleGraph = new Graph(false, false); +console.log(eventlist); -const pointA = new GraphNode(initialData); -const pointB = new GraphNode(secondEvent); - -sampleGraph.addPoints(pointA, pointB); - -sampleGraph.print(); - -export default {sampleEvent, sampleGraph}; \ No newline at end of file +export default { eventlist } diff --git a/src/main.ts b/src/main.ts index 3b02b73..01b182a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,7 @@ import data from "./lib/helpers/sample"; +const { eventlist } = data; -const { sampleEvent, sampleGraph } = data; -const content = JSON.stringify(sampleEvent.getEventData()); -console.log(sampleGraph.print()); - -export default content; +// export default content; // const parser = new DOMParser(); // const document = parser.parseFromString(content, 'text/html');