working version
This commit is contained in:
parent
63c24b575b
commit
21325cff77
7 changed files with 2157 additions and 0 deletions
5
.eslintrc.js
Normal file
5
.eslintrc.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
"extends": [
|
||||||
|
"eslint-config-prettier"
|
||||||
|
]
|
||||||
|
}
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
||||||
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
||||||
1945
package-lock.json
generated
Normal file
1945
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
22
package.json
Normal file
22
package.json
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "js-linkedlist",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "ssh://_gitea@git.alexanderk.net:3022/ak/js-linkedlist.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^8.43.0",
|
||||||
|
"eslint-config-prettier": "^8.8.0",
|
||||||
|
"prettier": "^2.8.8"
|
||||||
|
},
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
176
src/LinkedList.js
Normal file
176
src/LinkedList.js
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
import { Node } from "./Node.js";
|
||||||
|
|
||||||
|
// linked list factory
|
||||||
|
export const LinkedList = () => {
|
||||||
|
const CLU = {
|
||||||
|
firstNode: null,
|
||||||
|
lastNode: null,
|
||||||
|
totalNodes: 0
|
||||||
|
}
|
||||||
|
// adds a new node containing value to the end of the list
|
||||||
|
const append = (value) => {
|
||||||
|
// make node
|
||||||
|
const newNode = Node(value);
|
||||||
|
// set it to first node if we have no others
|
||||||
|
if (CLU.totalNodes === 0) {
|
||||||
|
CLU.firstNode = CLU.lastNode = newNode;
|
||||||
|
CLU.totalNodes++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
CLU.lastNode.nextNode = CLU.lastNode = newNode;
|
||||||
|
CLU.totalNodes++;
|
||||||
|
}
|
||||||
|
// adds a new node containing value to the start of the list
|
||||||
|
const prepend = (value) => {
|
||||||
|
// set it to first node if we have no others
|
||||||
|
if (CLU.totalNodes === 0) {
|
||||||
|
// make node
|
||||||
|
const newNode = Node(value);
|
||||||
|
CLU.firstNode = CLU.lastNode = newNode;
|
||||||
|
CLU.totalNodes++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// make node
|
||||||
|
const newNode = Node(value, CLU.firstNode);
|
||||||
|
CLU.firstNode = newNode;
|
||||||
|
CLU.totalNodes++;
|
||||||
|
}
|
||||||
|
// returns the total number of nodes in the list
|
||||||
|
const size = () => {
|
||||||
|
return CLU.totalNodes;
|
||||||
|
}
|
||||||
|
// returns the first node in the list
|
||||||
|
const head = () => {
|
||||||
|
return CLU.firstNode;
|
||||||
|
}
|
||||||
|
// returns the last node in the list
|
||||||
|
const tail = () => {
|
||||||
|
return CLU.lastNode;
|
||||||
|
}
|
||||||
|
// returns the node at the given index
|
||||||
|
const at = (index) => {
|
||||||
|
// set to first node
|
||||||
|
const MCP = {
|
||||||
|
currentNode: CLU.firstNode
|
||||||
|
}
|
||||||
|
// loop through LL to index
|
||||||
|
for (let i = 0; i < index; i++) {
|
||||||
|
MCP.currentNode = MCP.currentNode.nextNode;
|
||||||
|
}
|
||||||
|
return MCP.currentNode;
|
||||||
|
}
|
||||||
|
// removes the last element from the list
|
||||||
|
const pop = () => {
|
||||||
|
// gets second to last node
|
||||||
|
const penultimateNode = at(CLU.totalNodes - 2);
|
||||||
|
// erases from chain
|
||||||
|
penultimateNode.nextNode = null;
|
||||||
|
// updates node count
|
||||||
|
CLU.totalNodes = CLU.totalNodes - 1;
|
||||||
|
// catches the offchance
|
||||||
|
if (CLU.totalNodes === 0) {
|
||||||
|
CLU.firstNode = CLU.lastNode = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// returns true if the passed in value is in the list and otherwise returns false.
|
||||||
|
const contains = (value) => {
|
||||||
|
find(value) ? true : false;
|
||||||
|
}
|
||||||
|
// returns the index of the node containing value, or null if not found. !!!!!!!!!!!
|
||||||
|
const find = (value) => {
|
||||||
|
// set to first node
|
||||||
|
const MCP = {
|
||||||
|
currentNode: CLU.firstNode
|
||||||
|
}
|
||||||
|
// for all nodes
|
||||||
|
for (let i = 0; i < CLU.totalNodes; i++) {
|
||||||
|
// if node value matches, set to true
|
||||||
|
if (MCP.currentNode.value === value) {
|
||||||
|
bool = true;
|
||||||
|
}
|
||||||
|
// otherwise set to next node
|
||||||
|
MCP.currentNode = MCP.currentNode.nextNode;
|
||||||
|
}
|
||||||
|
return bool;
|
||||||
|
}
|
||||||
|
// print Nodes out and preview them in the console
|
||||||
|
const toString = () => {
|
||||||
|
// final String value
|
||||||
|
let finalStr = '';
|
||||||
|
// set to first node
|
||||||
|
const MCP = {
|
||||||
|
currentNode: CLU.firstNode
|
||||||
|
}
|
||||||
|
// loop through LL to index
|
||||||
|
for (let i = 0; i < CLU.totalNodes; i++) {
|
||||||
|
finalStr = finalStr + ` ( ${MCP.currentNode.value} ) ->`;
|
||||||
|
MCP.currentNode = MCP.currentNode.nextNode;
|
||||||
|
}
|
||||||
|
finalStr = finalStr + " null";
|
||||||
|
return finalStr;
|
||||||
|
}
|
||||||
|
// inserts a new node with the provided value at the given index
|
||||||
|
const insertAt = (value, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
prepend(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index === CLU.totalNodes) {
|
||||||
|
append(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index === CLU.totalNodes + 1) {
|
||||||
|
console.log("Your index value is too high!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// gets node at previous index
|
||||||
|
const prevNode = at(index - 1);
|
||||||
|
// gets node at current index
|
||||||
|
const currNode = at(index);
|
||||||
|
// makes new node, sets current node at index as next
|
||||||
|
const newNode = Node(value, currNode);
|
||||||
|
// sets itself as previous index node's next node
|
||||||
|
prevNode.nextNode = newNode;
|
||||||
|
// updates counter
|
||||||
|
CLU.totalNodes = CLU.totalNodes + 1;
|
||||||
|
}
|
||||||
|
// removes the node at the given index
|
||||||
|
const removeAt = (index) => {
|
||||||
|
// pops if final value
|
||||||
|
if (index === CLU.totalNodes - 1) {
|
||||||
|
pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index === 0) {
|
||||||
|
CLU.firstNode = CLU.firstNode.nextNode;
|
||||||
|
CLU.totalNodes = CLU.totalNodes - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// gets node at previous index
|
||||||
|
const prevNode = at(index - 1);
|
||||||
|
// sets its next node to the one ahead of the current one, effectively removing it from the chain
|
||||||
|
prevNode.nextNode = at(index + 1);
|
||||||
|
// removes a digit from the counter
|
||||||
|
CLU.totalNodes = CLU.totalNodes - 1;
|
||||||
|
// catches the offchance
|
||||||
|
if (CLU.totalNodes === 0) {
|
||||||
|
CLU.firstNode = CLU.lastNode = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
append,
|
||||||
|
prepend,
|
||||||
|
size,
|
||||||
|
head,
|
||||||
|
tail,
|
||||||
|
at,
|
||||||
|
pop,
|
||||||
|
contains,
|
||||||
|
find,
|
||||||
|
toString,
|
||||||
|
insertAt,
|
||||||
|
removeAt
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Node.js
Normal file
7
src/Node.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
// node factory
|
||||||
|
export const Node = (value = null, nextNode = null) => {
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
nextNode
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue