zoukankan      html  css  js  c++  java
  • javascript LinkedList js 双向循环链表 Circular Linked List

    javascript LinkedList:

    function Node(elem, prev, next) {
        this.elem = elem;
        this.prev = prev ? prev : null;
        this.next = next ? prev : null;
    }
    
    function LinkedList() {
        this.length = 0;
        this.head = null;
    
        var that = this;
        if (arguments.length > 0) {
            var a = arguments[0];
            if (a instanceof Array) {
                a.forEach(function(elem) {
                    that.push(elem);
                });
            }
        }
    }
    
    LinkedList.prototype.push = function(elem) {
        var newNode = new Node(elem);
    
        if (this.length === 0) {
            this.head = newNode;
            this.head.prev = newNode;
            this.head.next = newNode;
        } else {
            newNode.next = this.head;
            newNode.prev = this.head.prev;
            this.head.prev.next = newNode; // !!! CAUTION !!!
            this.head.prev = newNode;
        }
        ++this.length;
        return this.length;
    };
    
    // alias for push
    LinkedList.prototype.append = function(elem) {
        return this.push(elem);
    };
    
    LinkedList.prototype.unshift = function(elem) {
        var newNode = new Node(elem);
    
        if (this.length === 0) {
            this.head = newNode;
            this.head.prev = newNode;
            this.head.next = newNode;
        } else {
            newNode.next = this.head;
            newNode.prev = this.head.prev;
            this.head.prev.next = newNode; // !!! CAUTION !!!
            this.head.prev = newNode;
        }
        this.head = newNode;
        ++this.length;
        return this.length;
    };
    
    LinkedList.prototype.shift = function() {
        if (this.length === 0) {
            return null;
        }
        var head = this.head,
            node = new Node(head.elem);
    
        head.next.prev = head.prev;
        head.prev.next = head.next;
        delete(head);
    
        this.head = head.next;
        --this.length;
    
        return node.elem;
    };
    
    LinkedList.prototype.pop = function() {
        if (this.length === 0) {
            return null;
        }
        var tail = this.head.prev,
            node = new Node(tail.elem);
    
        tail.prev.next = tail.next;
        tail.next.prev = tail.prev;
    
        delete(tail);
        --this.length;
    
        return node.elem;
    };
    
    LinkedList.prototype._get = function(index) {
        if (index < 0 || index >= this.length) {
            throw new DOMException("LinkedList index out of bounds!");
        }
        if (index===0) {
            return this.head;
        }
        var pivot = Math.round(this.length / 2);
        var p = null, i;
        if (index <= pivot) {
            p = this.head; // head => tail
            for (i = 0; i < index; i++) {
                p = p.next;
            }
        } else {
            p = this.head.prev; // tail => head
            for (i = this.length - 1; i > index; i--) {
                p = p.prev;
            }
        }
        return p;
    };
    
    LinkedList.prototype._delete = function(node) {
        var retNode = new Node(node.elem);
    
        node.prev.next = node.next;
        node.next.prev = node.prev;
    
        var p = node.next;
        if (node===this.head) {
            this.head = p;
        }
        node = null;
    
        this.length--;
        return {
            p: 0 <this.length ? p : null,
            v: retNode.elem
        }
    };
    
    LinkedList.prototype._insertBefore = function(node, elem) {
        var newNode = new Node(elem);
        newNode.next = node;
        newNode.prev = node.prev;
        node.prev.next = newNode;
        node.prev = newNode;
        ++this.length;
        return newNode;
    };
    
    LinkedList.prototype.get = function(index) {
        var p = this._get(index);
        return p.elem;
    };
    
    LinkedList.prototype.splice = function(start,deleteCount,items) {
        var p = this._get(start), o, list = new LinkedList();
        while (deleteCount--) {
            o = this._delete(p);
            p = o.p;
            list.push(o.v);
            if (null===p) {break;}
        }
        var that = this;
        if (typeof items !== "undefined") {
            var i = 0;
            if (items instanceof Array) {
                for (i = 0; i < items.length; i++) {
                    p = that._insertBefore(p, items[i]);
                }
            } else if (items instanceof LinkedList) {
                for (i = 0; i < items.length; i++) {
                    p = that._insertBefore(p, items.get(i));
                }
            } else {
                that._insertBefore(p, items);
            }
        }
        return list;
    };
    
    LinkedList.prototype.forEach = function(callback) {
        var p = this.head,
            index = 0;
        do {
            callback(p.elem, index);
            p = p.next;
            index++;
        } while (p != this.head);
        return this;
    };
    
    LinkedList.prototype.map = function(callback) {
        var newList = new this.__proto__.constructor();
        this.forEach(function(elem) {
            newList.push(callback(elem));
        });
        return newList;
    };
    
    LinkedList.prototype.reduce = function(callback, initValue) {
        if (this === null) {
            throw new TypeError('LinkedList.prototype.reduce ' +
                'called on null or undefined');
        }
        if (typeof callback !== 'function') {
            throw new TypeError(callback + ' is not a function');
        }
        var acc = initValue,
            p = this.head;
        do {
            acc = callback(acc, p.elem);
            p = p.next;
        } while (p != this.head);
    
        return acc;
    };
    
    LinkedList.prototype.join = function(sep) {
        var s = "";
        if (this.length === 0) {
            return s;
        }
        if (this.length === 1) {
            return this.head.elem;
        }
        var p = this.head;
        do {
            s += p.elem.toString() + sep;
            p = p.next;
        } while (p != this.head.prev);
        s += p.elem.toString();
        return s;
    };
    
    LinkedList.prototype.toString = function() {
        return '[' + this.join(',') + ']';
    };
    
    LinkedList.prototype.insertBeforeIndex = function(index, elem) {
        if (index === 0) {
            this.unshift(elem);
            return this.length;
        }
        if (index >this.length) {
            throw new DOMException('index out of bounds');
        }
        if (index === this.length) {
            this.append(elem);
            return this.length;
        }
        var node = new Node(elem);
        if (index === this.length-1) {
            var tail = this.head.prev;
            node.next = tail;
            node.prev = tail.prev;
            tail.prev.next = node;
            tail.prev = node;
        } else {
            var p = this._get(index);
    
            node.next = p;
            node.prev = p.prev;
            p.prev.next = node;
            p.next.prev = node;
        }
        ++this.length;
    
        return this.length;
    };
    

      

      

    // Array like 

     1 // test
     2 var list = new LinkedList();
     3  
     4 for (var i = 1; i < 10; i++) {
     5     list.push(i);
     6 }
     7 for (i = 0; i < list.length; i++) {
     8     console.log(list.get(i));    // 1,2,3,4,5,6,7,8,9
     9 }
    10  
    11 // list.forEach(function(elem) {console.log(elem);});
    12 var newList = list.map(function(elem) {
    13     return elem - 1;
    14 });
    15 console.log(newList.toString()); //  0,1,2,3,4,5,6,7,8
    16 newList.shift();
    17 console.log(newList.toString()); // 1,2,3,4,5,6,7,8
    18  
    19 var oList = new LinkedList();
    20 oList.push({ x: 2 });
    21 oList.push({ x: 2 });
    22 oList.push({ x: 3 });
    23  
    24 var mul = oList.reduce(function(a, c) {
    25     return a * c.x;
    26 }, 1);
    27 console.log(mul); // 12
    map,reduce

     // test 2

    var a = [3, 12, 17, 16, 73, 32, 61, 46, 52, 49, 6, 5];
    var list = new LinkedList(a);
    console.log(list.toString());
    console.log('array: ' + a.length + ' list: ' + list.length);
    
    list.insertBeforeIndex(0, 99);
    console.log(list.toString());
    
    list.insertBeforeIndex(3, 99);
    console.log(list.toString());
    
    list.insertBeforeIndex(list.length, 100);
    console.log(list.toString());
    
    list.insertBeforeIndex(list.length-1, 98);
    console.log(list.toString());
    
    console.log(list.length);
    insertBeforeIndex

     // test splice

    function getTopN(a, n) {
    
        function _getMaxElem(a) {
            if (a.length === 0)
                throw "empty array";
    
            if (a.length === 1)
                return { index: 0, value: a[0] };
    
            var max = a.get(0), index = 0, c;
            for (var i = 0; i < a.length; i++) {
                c = a.get(i);
                if (c > max) {
                    max = c;
                    index = i;
                }
            }
            return {
                index: index,
                value: max
            }
        }
    
        var o = {}, b = [];
        while (n--) {
            o = _getMaxElem(a);
            b.push(o.value);
            a.splice(o.index, 1);
        }
    
        return b;
    }
    
    /**
     * 5 largest elements: [73,61,52,49,46]
     * -------------sorted------------------
     * [ 73, 61, 52, 49, 46, 32, 17, 16, 12, 6, 5, 3 ]
     */
    var a = [3, 12, 17, 16, 73, 32, 61, 46, 52, 49, 6, 5];
    var list = new LinkedList(a);
    var top5 = getTopN(list, 5);
    console.log('5 largest elements: [' + top5.toString() + ']');
    console.log('-------------sorted------------------');
    console.log(a.sort(function(a, b) { return b - a; }));
    

      

  • 相关阅读:
    postgis 利用 php 返回geojson格式数据
    openlayers 3读取加载geojson格式数据
    openlayers 3加载百度、高德、google瓦片地图
    ol2 和 bootstrap样式冲突的问题
    Openlayers 2 取消鼠标缩放地图的功能
    Struts2之2.5.10配置
    ol3修改右下键的Attribution
    openlayers 2 高亮显示元素以及通过属性查询高亮某一元素
    sql查看锁与解锁
    使用jQuery解析JSON数据
  • 原文地址:https://www.cnblogs.com/mingzhanghui/p/9317179.html
Copyright © 2011-2022 走看看