美文网首页
数据结构:链表

数据结构:链表

作者: 泰然自若_750f | 来源:发表于2020-05-13 13:49 被阅读0次

  • 什么是链表

链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。 链表中的基本数据以节点来表示,每个节点由元素+指针构成,元素是存储数据的存储单元,指针就是连接每个节点的地址数据

  1. 单链表

 /**
     * 链表节点
     */
    
    class Node
    {
        constructor(ele)
        {
            this.node=ele;
            this.next=null;
        }

    }
    /**
     * 链表
     */

    class LinkedList{

         constructor(){
              this.head=null;
              this.tail=null;
              this._length=0;
         }
         /**
          * 链表优势就是 添加复杂度低O(1),数组 O(n)
          * 
          * 添加
          * @param {*} ele 
          */
        append(ele){
               //执行 链 
               // var node={node:'xx' ,next:null} var head=node; var tail=node
                //  head === tail //true  
                // var newNode={node:'yy',next:null}
                // tail.next=newNode; // 执行结果  tail===head={node:'xx',next:{node:'yy',next:null}}
                // tail=newNode // 执行结果  head.next===tail===newNode
                // 多次 append 后  head....next===tail===newNode
            let node=new Node(ele);
            if(this._length===0)
            {
                this.head=node;
                this.tail=node;//记录最后一个节点
            
            }
            else{
                this.tail.next=node; 
                //此时 再让 (head) last [node][next] === tail
                this.tail=node;
            }
            this._length++;
        }
        

        /**
         * 插入链表
         * @param {*} ele 
         * @param {*} position 
         */
         insert(ele,position){
             if(typeof position !=='number' || position!==position)
             {
                throw new TypeError('position type error');
             }
             let node=new Node(ele);
             //空链表 直接插入即可
             if(position===0)
             {
                 node.next=this.head;
                 this.head=node;  
             }
             else{
                let i=0,cur=this.head,prev=null;
                //查找到需要插入位置的两个节点
                while(i<position)
                {
                    prev=cur;
                    cur=cur.next;
                    i++;   
                }
                //找到需要插入位置的两个链表节点
                //node1 =》 node2 修改为  node1 =》nodeNew=》node2 
                prev.next=node;
                node.next=cur;
             }
           
             this._length++;
             return true;

         }
         /**
          * 获取链表指定位置的
          * @param {*} position 
          */
          
         getByPosition(position){
               //判断传参是否合法
            if(!this.isCheckPosition(position)) return null;
            let i=0,cur=this.head;
            while(i<position)
            {
                cur=cur.next;
                i++;
            }
            return cur;

         }


         /**
          * 更新
          * @param {*} position 
          * @param {*} value 
          */

         update(position,value){
             let res=this.getByPosition(position);
             if(res){
                res.node=value;
                return true;
             }
             return false;
         }


         /**
          * 判断链表中是否包含某个元素
          * @param {*} value 
          */

         indexOf(value){
             if(this._length==0)
             {
                 return -1;
             }
             let cur=this.head,i=0;
             //查找
             while(cur)
             {
                if(cur.node===value){
                    return i;
                }
                else{
                     cur=cur.next;
                     i++;
                }
             }
             return -1;


         }

         /**
          * 移除
          * @param {*} position 
          */

         remove(position){
            if(!this.isCheckPosition(position)) return false;
            let i=0,cur=this.head,prev=null;
            while(i<position)
            {
                prev=cur;
                cur=cur.next;
                i++;
            }
            //找出需要删除的节点 让他的前一个节点的next 指向自己的next
            // node1[next=node2] =》 node2[next=node3]
            // prev=node1  cur.next=node3
             //node1[next=node3]
             prev.next=cur.next;
             return true;
         }
         /**
          * 
          * @param {*} position 
          */

         isCheckPosition(position){
              //判断传参是否合法
            if(typeof position !=='number' || position!==position)
            {
               throw new TypeError('position type error');
            }
            
            if(position.length>this._length)
            {
                return false;
            }
            return true;
         }

         
    }

    var  link=new LinkedList();
    link.append(1);
    link.append(2);
    link.append(3);
    link.append(4);

  • 双向链表

 function Node2(value){
         this.node=value;
         this.prev=null;
         this.next=null;
    }

  // var node1=new Node2(1);
    // var node2=new Node2(2);
    // var node3=new Node2(3);

    // var head=node1,tail=node1;
    
    // node2.prev=this.tail;
    // tail.next=node2;
    // tail=node2;

    // node3.prev=this.tail;
    // tail.next=node3;
    // tail=node3;


   class DoublyLinkedList{
         
        constructor(){
             this.head=null;
             this.tail=null;//指向 head的尾结点
             this._length=0;
        }
        /**
         * 新增
         * @param {*} ele 
         */
        append(ele){
            var node=new Node2(ele);
            if(this.head===null)
            {
                this.head=node;
                this.tail=node;
            }
            else{
                // 新节点的 prev 指向 尾结点
                 node.prev=this.tail;
                 // 尾结点指向 新节点
                 this.tail.next=node;
                 //更新尾
                 this.tail=node;
            }
            this._length++;

        }
        /**
         * 
         * @param {*} ele 
         * @param {*} position 
         */
        
        insert(ele,position){

            if(this._length===position)
            {
                 return this.append(ele);
            }

            let node=new Node2(ele),cur=this.head,i=0,prevNode=null;
            while(i<position)
            {
                prevNode=cur;
                cur=cur.next;
                i++;
            }
           //新节点 prev 指向 插入位置的前面节点
            node.prev=prevNode;
             // 插入位置的前面节点 next 指向新节点
            prevNode.next=node;
            //新节点 next 指向插入位置的后面节点
            node.next=cur;
            //插入位置后面的节点 prev 指向 新node
            cur.prev=node;
            this._length++;
            return true;
        }
   }
   var doublyLinkedList=new DoublyLinkedList();
   doublyLinkedList.append(1);
   doublyLinkedList.append(2);
   doublyLinkedList.append(3);
   doublyLinkedList.append(4);
   doublyLinkedList.append(6); //新增
    doublyLinkedList.insert(5,4); //插入节点

运行结果

image.png

相关文章

网友评论

      本文标题:数据结构:链表

      本文链接:https://www.haomeiwen.com/subject/bfsnnhtx.html