EXERCISE · AlgoCasts
Circular linked list
Given a linked list, return true if the list is circular, false if it is not.
Directions
Directions
Given a linked list, return true if the list is circular, false if it is not.
Examples#
JS
const l = new List();const a = new Node('a');const b = new Node('b');const c = new Node('c');l.head = a;a.next = b;b.next = c;c.next = b;circular(l) // trueTry it first#
Copy the stub, make the 4 tests pass on your machine, then open the solution. The reveal is remembered per page in this browser.
JSexercises/circular/index.js
function circular(list) {} module.exports = circular;Solution#
JScompleted_exercises/circular/index.js
function circular(list) { let slow = list.getFirst(); let fast = list.getFirst(); while (fast.next && fast.next.next) { slow = slow.next; fast = fast.next.next; if (slow === fast) { return true; } } return false;} module.exports = circular;const circular = require('./index');const L = require('./linkedlist');const List = L.LinkedList;const Node = L.Node; test('circular', () => { expect(typeof circular).toEqual('function');}); test('circular detects circular linked lists', () => { const l = new List(); const a = new Node('a'); const b = new Node('b'); const c = new Node('c'); l.head = a; a.next = b; b.next = c; c.next = b; expect(circular(l)).toEqual(true);}); test('circular detects circular linked lists linked at the head', () => { const l = new List(); const a = new Node('a'); const b = new Node('b'); const c = new Node('c'); l.head = a; a.next = b; b.next = c; c.next = a; expect(circular(l)).toEqual(true);}); test('circular detects non-circular linked lists', () => { const l = new List(); const a = new Node('a'); const b = new Node('b'); const c = new Node('c'); l.head = a; a.next = b; b.next = c; c.next = null; expect(circular(l)).toEqual(false);}); class Node { constructor(data, next = null) { this.data = data; this.next = next; }} class LinkedList { constructor(values = []) { this.head = null; for (let value of values) { this.insertLast(value); } } clear() { this.head = null; } size() { let counter = 0; let node = this.head; while (node) { counter++; node = node.next; } return counter; } getAt(index) { if (!this.head) { return null; } let counter = 0; let node = this.head; while (node) { if (counter === index) { return node; } node = node.next; counter++; } return null; } insertAt(data, index) { if (!this.head) { this.head = new Node(data); return; } if (index === 0) { this.head = new Node(data, this.head); return; } let counter = 1; let previous = this.head; let node = this.head.next; while (node) { if (counter === index) { previous.next = new Node(data, node); return; } previous = node; node = node.next; counter++; } previous.next = new Node(data, node); } removeFirst() { if (!this.head) { return; } this.head = this.head.next; } removeLast() { if (!this.head) { return; } if (!this.head.next) { this.head = null; return; } let previous = this.head; let node = this.head.next; while (node.next) { previous = node; node = node.next; } previous.next = null; } removeAt(index) { if (!this.head) { return; } let counter = 0; let node = this.head; while (node) { if (counter === index - 1) { if (node.next) { return (node.next = node.next.next); } else { return (node.next = null); } } node = node.next; counter++; } } getFirst() { return this.head; } insertFirst(data) { this.head = new Node(data, this.getFirst()); } getLast() { if (!this.head) { return null; } let node = this.head; while (node.next) { node = node.next; } return node; } insertLast(data) { const last = this.getLast(); if (last) { last.next = new Node(data); return last.next; } else { this.head = new Node(data); return this.head; } } forEach(fn) { if (!this.head) { return null; } let node = this.head; while (node) { fn(node); node = node.next; } } *[Symbol.iterator]() { let node = this.head; while (node) { yield node; node = node.next; } }} module.exports = { Node, LinkedList }; Verbatim from the repo at 30cf7634. Alternate tabs are the commented-out solutions with the leading // removed and nothing else changed. Run the tests locally with npx jest circular inside the fork.
See also