数据结构:链表

  • 什么是链表

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

  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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341