zoukankan      html  css  js  c++  java
  • js创建链表

    首先要明确,我们为什么要创建链表呢?数组的大小是固定的,从数组的起点或中间插入或移除的成本很高,因为需要移动元素。尽管JS的Array类方法可以做这些,但是情况也是这样。链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身和指向下一个元素的指针组成。

    相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代到列表直到找到所需元素。

    好了,闲话少叙,正式创建链表!
    我们使用动态原型模式来创建一个链表。列表最后一个节点的下一个元素始终是null。

    function LinkedList() {
        //先创建一个节点
        function Node(element) {
            this.element = element;
            this.next = null;
        }
        this.head = null;
        this.length = 0;
    
        //通过对一个方法append判断就可以知道是否设置了prototype
        if ((typeof this.append !== 'function') && (typeof this.append !== 'string')) {
            //添加元素
            LinkedList.prototype.append = function(element) {
                var node = new Node(element);
                var current;
    
                if (this.head == null) {
                    this.head = node;
                } else {
                    current = this.head;
                    while (current.next != null) {
                        current = current.next;
                    }
                    current.next = node;
                }
                this.length++;
            };
    
            //插入元素,成功true,失败false
            LinkedList.prototype.insert = function(position, element) {
                if (position > -1 && position < this.length) {
                    var current = this.head;
                    var node = new Node(element);
                    var previous;
                    var index = 0;
                    if (position == 0) {
                        node.next = current;
                        this.head = node;
                    } else {
                        while (index++ < position) {
                            previous = current;
                            current = current.next;
                        }
                        node.next = current;
                        previous.next = node;
                    }
                    this.length++;
                    return true;
                } else {
                    return false;
                }
            };
    
            //根据位置删除指定元素,成功 返回元素, 失败 返回null
            LinkedList.prototype.removeAt = function(position) {
                if (position > -1 && position < this.length) {
                    var current = this.head;
                    var previous = null;
                    var index = 0;
    
                    if (position == 0) {
                        this.head = current.next;
                    } else {
                        while (index++ < position) {
                            previous = current;
                            current = current.next;
                        }
                        previous.next = current.next;
                    }
                    this.length--;
                    return current.element;
                } else {
                    return null;
                }
            };
    
            //根据元素删除指定元素,成功 返回元素, 失败 返回null
            LinkedList.prototype.remove = function(element) {
                var index = this.indexOf(element);
                return this.removeAt(index);
            };
    
            //返回给定元素的索引,如果没有则返回-1
            LinkedList.prototype.indexOf = function(element) {
                var current = this.head;
                var index = 0;
                while (current) {
                    if (current.element === element) {
                        return index;
                    }
                    current = current.next;
                    index++;
                }
                return -1;
            };
    
            LinkedList.prototype.isEmpty = function() {
                return this.length === 0;
            };
            LinkedList.prototype.size = function() {
                return this.length;
            };
            LinkedList.prototype.toString = function() {
                var string = '';
                var current = this.head;
                while (current) {
                    string += current.element;
                    current = current.next;
                }
                return string;
            };
            LinkedList.prototype.getHead = function() {
                return this.head;
            };
        }
    }

    链表的基本使用

    var linkedList = new LinkedList();
        console.log(linkedList.isEmpty());//true;
        linkedList.append('huang');
        linkedList.append('du')
        linkedList.insert(1,'cheng');
        console.log(linkedList.toString());//huangchengdu
        console.log(linkedList.indexOf('du'));//2
        console.log(linkedList.size());//3
        console.log(linkedList.removeAt(2));//du
        console.log(linkedList.toString());//huangcheng

    创建双向链表

    在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素。

    双向链表和链表的区别就是有一个tail属性,所以必须重写insert、append、removeAt方法。每个节点对应的Node也多了一个prev属性。

     
    //寄生组合式继承实现,详见javascript高级程序设计第七章
       function inheritPrototype(subType, superType) {
           function object(o) {
               function F() {}
               F.prototype = o;
               return new F();
           }
           var prototype = object(superType.prototype);
           prototype.constructor = subType;
           subType.prototype = prototype;
       }
       function DoublyLinkedList() {
           function Node(element) {
               this.element = element;
               this.next = null;
               this.prev = null;
           }
           this.tail = null;
           LinkedList.call(this);
           //与LinkedList不同的方法自己实现。
           this.insert = function(position, element) {
               if (position > -1 && position <= this.length) {
                   var node = new Node(element);
                   var current = this.head;
                   var previous;
                   var index = 0;
                   if (position === 0) {
                       if (!this.head) {
                           this.head = node;
                           this.tail = node;
                       } else {
                           node.next = current;
                           current.prev = node;
                           this.head = node;
                       }
                   } else if (position == this.length) {
                       current = this.tail;
                       current.next = node;
                       node.prev = current;
                       this.tail = node;
                   } else {
                       while (index++ < position) {
                           previous = current;
                           current = current.next;
                       }
                       previous.next = node;
                       node.next = current;
                       current.prev = node;
                       node.prev = previous;
                   }
                   this.length++;
                   return true;
               } else {
                   return false;
               }
           };
           this.append = function(element) {
               var node = new Node(element);
               var current;
               if (this.head === null) {
                   this.head = node;
                   this.tail = node;
               } else {
                   current = this.head;
                   while (current.next !== null) {
                       current = current.next;
                   }
                   current.next = node;
                   node.prev = current;
                   this.tail = node;
               }
               this.length++;
           };
           this.removeAt = function(position) {
               if (position > -1 && position < this.length) {
                   var current = this.head;
                   var previous;
                   var index = 0;
                   if (position === 0) {
                       this.head = current.next;
                       if (this.length === 1) {
                           this.tail = null;
                       } else {
                           this.head.prev = null;
                       }
                   } else if (position === (this.length - 1)) {
                       current = this.tail;
                       this.tail = current.prev;
                       this.tail.next = null;
                   } else {
                       while (index++ < position) {
                           previous = current;
                           current = current.next;
                       }
                       previous.next = current.next;
                       current.next.prev = previous;
                   }
                   this.length--;
                   return current.element;
               } else {
                   return false;
               }
           };
       }
       inheritPrototype(DoublyLinkedList, LinkedList);

    双向链表的基本使用

    var doublyList = new DoublyLinkedList();
        console.log(doublyList.isEmpty()); //true;
        doublyList.append('huang');
        doublyList.append('du')
        doublyList.insert(1, 'cheng');
        console.log(doublyList.toString()); //huangchengdu
        console.log(doublyList.indexOf('du')); //2
        console.log(doublyList.size()); //3
        console.log(doublyList.removeAt(2)); //du
        console.log(doublyList.toString()); //huangcheng
  • 相关阅读:
    Swagger入门
    UOS
    Java多线程
    英语语法小知识-Unit1
    MVVM
    Vue入门
    Mybatis入门
    Python pip install
    js 触发LinkButton点击事件,执行后台方法
    ajax 请求 ascx
  • 原文地址:https://www.cnblogs.com/greatluoluo/p/6308828.html
Copyright © 2011-2022 走看看