feat(curriculum): add Linked list lab (#56046)

Co-authored-by: Zaira <33151350+zairahira@users.noreply.github.com>
This commit is contained in:
Dario-DC 2024-09-18 09:37:07 +02:00 committed by GitHub
parent df08bef374
commit 295f537c99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 293 additions and 1 deletions

View File

@ -2127,7 +2127,12 @@
"nixz": { "title": "262", "intro": [] },
"zywg": { "title": "263", "intro": [] },
"wraf": { "title": "264", "intro": [] },
"kwxs": { "title": "265", "intro": [] },
"lab-linked-list-class": {
"title": "Build a Linked List Class",
"intro": [
"For this lab, you will build a linked list class using JavaScript."
]
},
"muyw": { "title": "266", "intro": [] },
"mvzb": { "title": "267", "intro": [] },
"rmpy": { "title": "268", "intro": [] },

View File

@ -0,0 +1,9 @@
---
title: Introduction to the Build a Linked List Class
block: lab-linked-list-class
superBlock: front-end-development
---
## Introduction to the Build a Linked List Class
For this lab, you will build a linked list class using JavaScript.

View File

@ -0,0 +1,11 @@
{
"name": "Build a Linked List Class",
"isUpcomingChange": true,
"usesMultifileEditor": true,
"blockType": "lab",
"dashedName": "lab-linked-list-class",
"order": 265,
"superBlock": "front-end-development",
"challengeOrder": [{ "id": "66dadcf18df3a76104054d95", "title": "Build a Linked List Class" }],
"helpCategory": "JavaScript"
}

View File

@ -0,0 +1,267 @@
---
id: 66dadcf18df3a76104054d95
title: Build a Linked List Class
challengeType: 14
dashedName: build-a-linked-list-class
---
# --description--
In this lab, you'll build a linked list, which is a linear collection of data elements, called <dfn>nodes</dfn>, where each node points to the next node in the linked list. Each node in a linked list contains two key pieces of information: the element itself, and a reference to the next node.
**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
**User Stories:**
1. You should create a class named `LinkedList` to represent a linked list data structure.
1. Each time a new `LinkedList` object is instantiated, its `length` and `head` properties should be set to `0` and `null`, respectively.
1. The `LinkedList` class should have a property `Node`, which is a class instantiated with an `element` property set to the value passed at the instantiation, and a `next` property set to `null`.
1. The `LinkedList` class should have a method `isEmpty` that returns `true` if the linked list is empty, and `false` otherwise.
1. The `LinkedList` class should have a method `add` that creates a `Node` object from its argument and adds it to the linked list.
1. The `add` method should either set the head to the new node when the node to be added is the first, or set the `next` property of the last node in the linked list to the node to be added.
1. Each time a new node is added to the list the length of the list should be incremented.
1. The `LinkedList` class should have a method `remove` that takes a single argument and removes the corresponding node from the list.
1. Whenever a node is removed from the linked list, the `next` property of the previous node should be set to the following node, and the length of the list should be decremented.
# --hints--
Your `LinkedList` class should instantiate objects with the `length` property set to `0`.
```js
const test = new LinkedList();
assert.strictEqual(test.length, 0);
```
Your `LinkedList` class should instantiate objects with the `head` property set to `null`.
```js
const test = new LinkedList();
assert.strictEqual(test.head, null);
```
Your `LinkedList` class should have a property `Node`.
```js
const test = new LinkedList();
assert.property(test, "Node");
```
Your `Node` property should be a class that instantiates objects with an `element` property set to the value passed at the instantiation.
```js
const test = new LinkedList();
const node = new test.Node("pig");
assert.strictEqual(node.element, "pig");
```
Your `Node` property should be a class that instantiates objects with a `next` property set to `null`.
```js
const test = new LinkedList();
const node = new test.Node("pig");
assert.strictEqual(node.next, null);
```
Your `LinkedList` class should have an `add` method.
```js
const test = new LinkedList();
assert.typeOf(test.add, 'function');
```
Your `add` method should assign `head` to the first node object added to the linked list.
```js
const test = new LinkedList();
test.add("pig");
const expected = { element: "pig", next: null }
assert.deepEqual(test.head, expected);
```
Your `add` method should set the `next` property of the last node in the linked list to the node to be added.
```js
const test = new LinkedList();
test.add("pig");
test.add("dog")
const expected = { element: "pig", next: {element: "dog", next: null} }
assert.deepEqual(test.head, expected);
```
Each time a new node is added to the list the `length` of the list should be incremented.
```js
const test = new LinkedList();
test.add("pig");
assert.strictEqual(test.length, 1);
test.add("dog");
assert.strictEqual(test.length, 2);
test.add("sheep");
assert.strictEqual(test.length, 3);
```
Your `LinkedList` class should have an `isEmpty` method.
```js
const test = new LinkedList();
assert.typeOf(test.isEmpty, 'function');
```
Your `isEmpty` method should return `false` when there is at least one element in the linked list.
```js
const test = new LinkedList();
test.add('pig');
test.add('dog');
test.add('kitten');
assert.isFalse(test.isEmpty());
```
Your `isEmpty` method should return `true` when there are no elements in linked list.
```js
const test = new LinkedList();
assert.isTrue(test.isEmpty());
```
The previous node in your `LinkedList` class should have a reference to the newest node created.
```js
const test = new LinkedList();
test.add("pig");
test.add("dog")
test.add("sheep");
assert(test.head.next.element === 'dog' && test.head.next.next.element === "sheep");
```
Your `LinkedList` class should have a `remove` method.
```js
const test = new LinkedList();
assert.typeOf(test.remove, 'function');
```
Your `remove` method should reassign `head` to the second node when the first node is removed.
```js
const test = new LinkedList();
test.add("pig");
test.add("dog");
test.add("sheep");
test.remove("pig");
const expected = { element: "dog", next: {element: "sheep", next: null} }
assert.deepEqual(test.head, expected);
```
Your `remove` method should decrease the `length` of the linked list by one for every node removed.
```js
const test = new LinkedList();
test.add("pig");
test.add("dog");
test.add("sheep");
test.remove("pig");
assert.strictEqual(test.length, 2);
test.remove("dog");
assert.strictEqual(test.length, 1);
test.remove("sheep");
assert.strictEqual(test.length, 0);
```
Your `remove` method should reassign the reference of the previous node of the removed node to the removed node's `next` reference.
```js
const test = new LinkedList();
test.add("pig");
test.add("dog");
test.add("sheep");
test.add("cat");
test.remove("sheep");
const expected = { element: "pig", next: {element: "dog", next: {element: "cat", next: null}} }
assert.deepEqual(test.head, expected);
```
Your `remove` method should not change the linked list if the element does not exist in the linked list.
```js
const test = new LinkedList();
test.add("pig");
test.add("dog");
test.add("sheep");
test.add("cat");
test.remove("elephant");
const expected = { element: "pig", next: {element: "dog", next: {element: "sheep", next: {element: "cat", next: null}}} }
assert.deepEqual(test.head, expected);
```
# --seed--
## --seed-contents--
```js
```
# --solutions--
```js
class LinkedList {
constructor() {
this.length = 0;
this.head = null;
}
Node = class {
constructor(element) {
this.element = element;
this.next = null;
}
}
isEmpty() {
return this.length === 0;
}
add(element) {
const node = new this.Node(element)
if (this.isEmpty()) {
this.head = node;
} else {
let currentNode = this.head;
while (currentNode.next !== null) {
currentNode = currentNode.next;
}
currentNode.next = node;
}
this.length++;
}
remove(element) {
if (this.isEmpty()) {
return
}
let previousNode;
let currentNode = this.head;
while (currentNode.next !== null && currentNode.element !== element) {
previousNode = currentNode;
currentNode = currentNode.next;
}
if (currentNode.next === null && currentNode.element !== element) {
return;
} else if (previousNode) {
previousNode.next = currentNode.next
} else {
this.head = currentNode.next;
}
this.length--
}
}
```