zoukankan      html  css  js  c++  java
  • [Algorithm] Linked List Data Structure in JavaScript

    A linked list is a collection of items where each item points to the next one in the list. Because of this structure, linked lists are very slow when searching for an item at a particular index. An array, by comparison, has quick gets when searching for an index, but a linked list must start at the beginning, often called the "head", and loop through each item's next property until we arrive at the item. This makes gets in a linked list an operation that takes O(n) time.

    While gets might be slow in a linked list, it's other operations, like push and delete come with some great benefits we will see in the lesson.

    /**
     * Linked list
     * 
     * API:
     * push
     * pop
     * get
     * delete
     * isEmpty
     * print
     */
    
     function createNode(value) {
         return {
             value,
             next: null
         }
     }
    
     function createLinkedList() {
         return {
             head: null,
             tail: null,
             length: 0,
             push(value) {
                 /**Key takeaway: 
                  *  Assign new node to current tail's next value
                  *  Then
                  *  Reassign the tail to new node
                  */
                 // Create Node
                const node = createNode(value);
    
                // If this is the first one
                if (this.head === null) {
                    this.head = node
                    this.tail = node
                    this.length++;
                    return node;
                }
    
                // if there already has nodes
                this.tail.next = node;
                this.tail = node;
                this.length++;
                return node;
             },
             pop() {
                 const node = this.tail;
                 // if this is no node
                 if (!this.head) {
                     return null;
                 }
    
                 // if there is one node
                 if (this.head === this.tail) {
                     this.head = null;
                     this.tail = null;
                     return node;
                 }
    
                 let current = this.head;
                 let penultimate = null;
    
                 while (current) {
                    const {next} = current;
                    if (next && next == this.tail) {
                        penultimate = current;
                        break;
                    }
                    current = current.next;
                 }
                 penultimate.next = null;
                 this.tail = penultimate;
                 this.length--;
                 return node;
             },
             get(index = 0) {
                // no node in the list, return null
                if (!this.head) {
                    return null;
                }
    
                // if the index < 0 or > length - 1, out of range
                if (index < 0 || index > this.length - 1) {
                    return null;
                }
    
                // if index = 0, then return the first
                if (index === 0) {
                    return this.head;
                }
    
                let current = this.head;
                let i = 0;
                while (i < index) {
                    i++;
                    current = current.next;
                }
    
                return current;
             },
             delete(index = 0) {
                 /**
                  * Key takewawy:
                  * If we delete tail, we need to reassign the tail
                  */
                // no node in the list, return null
                if (!this.head) {
                    return null;
                }
    
                // if the index < 0 or > length - 1, out of range
                if (index < 0 || index > this.length - 1) {
                    return null;
                }
    
                // if index = 0, then return the first
                if (index === 0) {
                    const node = this.head;
                    this.head = node.next;
                    this.length--;
                    return node;
                }
    
                let i = 0;
                let current = this.head;
                let previous = null;
    
                while (i < index) {
                    i++;
                    previous = current;
                    current = current.next;
                }
    
                const deleted = current;
                previous.next = deleted.next;
    
                // If we delete the tail, we need to reassign tail
                if (previous.next === null) {
                    this.tail = previous;
                }
    
                this.length--;
                return deleted;
             },
             isEmpty() {
                 return this.length === 0;
             },
             print() {
                /**Key takeway: 
                 *  remember to assign next node to current 
                 *  Move the while loop
                 * */
                let nodes = [];
    
                if (!this.head) {
                    return 'Empty list';
                }
    
                let current = this.head;
                while (current) {
                    nodes.push(current.value);
                    current = current.next;
                }
                
                return nodes.join(' => ');
             }
         };
     }
    
     module.exports = {createLinkedList}

    test:

    const {createLinkedList} = require('../src/linked-list');
    
    describe('linked list', () => {
        test('push: should add node into array', () => {
            const l = createLinkedList();
            // linked list should be empty
            expect(l.isEmpty()).toBe(true);
            // push a new node
            l.push('a');
            expect(l.isEmpty()).toBe(false);
            expect(l.length).toEqual(1);
            expect(l.print()).toEqual('a');
            // push a second node
            l.push('b');
            expect(l.length).toEqual(2);
            expect(l.print()).toEqual('a => b');
        });
    
        test('pop: should remove the last node from the list', () => {
            const l = createLinkedList();
            l.push('a');
            l.push('b');
            l.push('c');
            expect(l.length).toEqual(3);
            const p = l.pop();
            expect(p.value).toEqual('c');
            expect(l.length).toEqual(2);
        });
    
        test('get: should return the node for the given index', () => {
            const l = createLinkedList();
            // empty list, return null
            expect(l.get(0)).toBeNull();
            l.push('a');
            l.push('b');
            l.push('c');
            expect(l.length).toEqual(3);
            // out of index, retur null
            expect(l.get(-1)).toBeNull();
            expect(l.get(4)).toBeNull();
    
            // return the head
            expect(l.get(0).value).toEqual('a');
    
            // index in range not head
            expect(l.get(2).value).toEqual('c');
        });
    
        test('delete: should delete the node from the given index', () => {
            const l = createLinkedList();
            // empty list, return null
            expect(l.delete(0)).toBeNull();
            l.push('a');
            l.push('b');
            l.push('c');
            expect(l.length).toEqual(3);
            // out of index, retur null
            expect(l.delete(-1)).toBeNull();
            expect(l.delete(4)).toBeNull();
            // return the head
            expect(l.delete(0).value).toEqual('a');
            expect(l.length).toEqual(2);
            // delete the tail, reassign the tail
            expect(l.delete(1).value).toEqual('c');
            expect(l.tail.value).toEqual('b');
        });
    });
  • 相关阅读:
    关于c#.net 使用自动生成的TableAdapter类的Insert、update方法无效
    .net 字符流下载 迅雷下载问题
    win7 64位系统下使用Oracle的问题
    使用vs2010发布.net framework2.0的网站出现的 分析器错误
    c博客作业我的第一篇博客
    C博客作业01分支,顺序结构1
    机器学习特训营前四次课总结
    ASP.NET应用程序与页面生命周期
    asp.net 获取文件的详细属性,大小,修改日期,所在位置等
    Json string value cannot have line breaks(解决方法)
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10117286.html
Copyright © 2011-2022 走看看