zoukankan      html  css  js  c++  java
  • 数据结构与算法 JavaScript实现链表

    链表存储有序的指向元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素有一个存储元素本身节点和一个 指向下一元素的引用组成。

    1.创建一个链表

     首先初始化链表LinkedList类

    function LinkedList(){
        var Node = function element(){
            this.element = element;
            this.next = null
        }
    
    var length = 0;
    var head = null;
    
    this.append = function(element){};
    this.insert = function(position,element){};
    this.removeAt = function(positon){};
    this.remove = function(element){};
    this.indexOf = function(element){};
    this.isEmpty = function(){};
    this.size = function(){};
    this.getHead = function(){};
    this.toString = function(){};
    this.print = function(){};
    }

    1.1 向链表尾部追加元素

    有两种情况,一种链表为空,添加的是第一个元素,另一种是链表不为空,向其追加元素

    this.append = function(element){
        var node = new Node(element),
            current;
    
        if (head===null) {
            head = node;
        }
        else{
            current = head;
            while(current.next){
                current = current.next;
            }
            current.next = node;
        }
        
        length++
    };

    1.2 从链表中移除元素

    移除也有两种场景,第一种是移除第一个元素,第二种是移除第一个以外的任意元素; 实现两种移除方法:第一种是从特定位置移除一个元素,第二种是根据元素的值移除元素

    首先实现从给定位置移除一个元素的方法

    this.removeAt = function(positon){
        // 检查越界值
        if (positon>-1&&positon<length) {
            var current = head,
                previous,
                index=0;
            // 移除第一项
            if (positon===0) {
                head = current.next;
            }
            else{
                while(index++<positon){
                    previous = current;
                    current = current.next;
                }
                // 将previous与current的下一项链接起来,跳过current,从而删除current
                previous.next = current.next;
            }
            length--;
            // 返回被删除的元素
            return current.element
        }
        else{
            return null;
        }
    };

    1.3 在任意位置插入一个元素

    以下是insert方法的实现买这个方法可以再任意位置插入一个元素

    this.insert = function(position,element){
        // 检查越界值
        if (positon>-1&&positon<length) {
            var node = new Node(element),
                current = head,
                privious,
                index = 0;
            // 在第一个位置插入
            if (positon===0) {
                node.next = current;
                head = node;
            }
            else{
                while(index++<positon){
                    previous = current;
                    current = current.next;
                }
                node.next = current;
                previous.next = node;
            }
            length++;
            return true;
        }
        else{
            return false;
        }
    };

    1.4 其它方法的实现

    1.toString方法

    this.toString = function(){
        var current = head,
            string = '';
        while(current){
            string += ","+current.element;
            current = current.next;
        }
        return string.slice(1);
    };

    2.indexOf方法

    this.indexOf = function(element){
        var current = head,
            index = 0;
    
        while(current){
            if(element===current.element){
                return index;
            }
            index++;
            current = current.next;
        }
        return -1;
    };

    实现了这个方法之后,就可以实现上文中提到的移除指定元素的方法remove

    this.remove = function(element){
        var index = this.indexOf(element);
        return this.removeAt(index);
    };

    2.isEmpty,size,getHead方法

    this.isEmpty = function(){
        return length = 0;
    };
    this.size = function(){
        return length;
    };
    this.getHead = function(){
        return head;
    };

    isEmpty方法判断链表是否为空,size方法返回链表的长度,getHead返回链表的一个节点

    2.双向链表

    双向链表中:一个链向下一个元素,另一个链向前一个元素

    function DoubleLinkedList(){
        var Node = function(element){
            this.element = element;
            this.next = null;
            this.prev = null;
        };
    
        var length = 0;
        var head = null;
        var tail = null;
    }

     双向链表提供了两种迭代链表的方法,从头到尾或者从尾到头。

    2.1 在任意位置插入一个元素

    this.insert = function(positon,element){
            // 检查越界值
            if (positon>-1&&positon<length) {
                var node = new Node(element),
                    current = head,
                    previous,
                    index = 0;
                // 在第一个位置插入
                if (positon===0) {
                    if (!head) {
                        head = node;
                        tail = node;
                    }
                    else{
                        node.next = current;
                        current.prev = node;
                        head = node;
                    }
                }
                else if (positon === length) {
                    current = tail;
                    current.next = node;
                    node.prev = current;
                    tail = node;
                }
                else{
                    while(index++<positon){
                        previous = current;
                        current = current.next;
                    }
                    node.next = current;
                    previous.next = node;
    
                    current.previous = node;
                    node.prev = previous;
                } 
    
                length++;
    
                return true;
            }
            else{
                return false;
            }
        }

    2.2 从任意位置移除元素

    this.removeAt = function(){
            // 检查越界值
            if (positon>-1&&positon<length){
                var current = head,
                    previous,
                    index = 0;
                // 移除第一项
                if (positon === 0) {
                    head = current.next;
                    // 如果只有一项,更新tail
                    if (length === 1) {
                        tail = null;
                    }
                    else{
                        head.prev = null;
                    }
                }
                else if(positon === length-1){
                    current = tail;
                    tail = current.prev;
                    tail.next = null;
                }
                else{
                    while(index++<positon){
                        previous = current;
                        current = current.next;
                    }
    
                    // 将previous和current的下一项链接起来
                    previous.next = current.next;
                    current.next.prev = previous;
                }
                length--;
    
                return current.element;
            }
            else{
                return null;
            }
        }

    3.循环链表

    循环链表和链表唯一区别就是,最后一个元素指向下一个元素的指针不是引用null,而是指向第一个元素。

  • 相关阅读:
    【原】WPF客户端只能启动一次
    【转载】U3D 游戏引擎之游戏架构脚本该如何来写
    【转载】u3d游戏客户端架构(---)
    【转载】asp.net 后台弹出提示框
    【转载】浅谈Excel开发:一 Excel 开发概述
    MyBatis 学习
    windows下关闭指定端口服务,解决tomcat端口占用问题
    中文用户名的js检验正则
    演讲稿
    面向对象和面向过程,python中的类class,python中程序的入口——main方法,
  • 原文地址:https://www.cnblogs.com/Cathamerst/p/7217630.html
Copyright © 2011-2022 走看看