javascript:数据结构——链表

什么是链表?

链表是有序的列表, 链表是以节点的方式来存储,是链式存储。
每个节点包含item域,next指针(指向下一个节点),即就是链表中的每一个元素都带有下一个元素的位置(next)

image.png

链表的节点不一定连续存储,是离散的状态

双向链表

每个链表不仅带有next这一项,还有previous这一项
image.png

双向循环列表

image.png

链表操作

1、添加(指定添加元素 尾部添加元素)
image.png

2、移除(指定位置(下标)移除元素 移除元素元素)
image.png

链表尾添加元素

1、如果链表为空的情况下,给链表尾添加元素,同时要把链表头设置成第一个添加的元素,长度++
2、链表不为空,添加元素到最后,链表尾的标志是node.next == null,即就是
代码

var LinkedList = function(){

  // 链表头

  var head = null;

  // 链表长度

  var length = 0;

  // 辅助类:节点

  var Node = function(element){

    this.next = null;

    this.element = element;

  }

​

  // 向链表尾添加元素

  this.append = function(element){

    const n = new Node(element);

    if(head == null){

      head = n

    }else{

      //先定义一个变量来当前链表

      var c = head;

      //循环并判断当前链表的next是否为null

      while(c.next){

        c = c.next

      }

      //如果为null的话就说明当前链表是最后一项,就可以向链表尾添加元素,即就是链表尾的next志向新添加的元素

      c.next = n;

    }

    length++

  }
  this.getHead = function(){

    return head;

  }

}

向链表某一位置添加元素

在有效的位置才能添加元素,添加位置不能小于表头位置,不能大于表尾
1、如果要添加到链表头的情况下,那么新加的元素是列表头,并且新加元素的next指向原本的列表头
2、指定位置,要记录添加位置的前后链表,从头开始循环记录链表的第几项(相当于数组的下标),当下标等于插入位置的时候,就要交换位置

var LinkedList = function () {

  // 链表头

  var head = null;

  // 链表长度

  var length = 0;

  // 辅助类:节点

  var Node = function (element) {

    this.next = null;

    this.element = element;

  }

  

  // 向链表某一位置添加元素

  this.inster = function (position, element) {

​

    if (-1 < position && position < length) {

      const n = new Node(element);

      if (position == 0) {

        var c = head;

        head = n;

        head.next = c;

      } else {

        var c = head;  //当前表

        var p = null;  //前一个表

        var index = 0;  //用来记录链表的第几项

        while (index < position) { //当index小于position的时候说明还没有走到需要添加位置的下标,需要重复执行并判断

          p = c; // 把当前的赋值给前一个

          c = c.next;  //把当前的next赋值给当前的表

          index++;

        }

        // 循环退出就相当于 index == position,说明要添加到当前index的位置。添加的话是需要在上一个表和当前表中间添加元素,

        // 这样把上一个表的next指向要添加的元素,让当前新添加的元素的next指向当前表就ok了

        p.next = n;

        n.next = c;

      }
      length++
    }
  }

  this.getHead = function () {

    return head;

  }

}

var l = new LinkedList();

l.append(1)

l.append(2)

l.append(3)

l.inster(2, "p")

删除链表某一位置元素

var LinkedList = function () {

  // 链表头

  var head = null;

  // 链表长度

  var length = 0;

  // 辅助类:节点

  var Node = function (element) {

    this.next = null;

    this.element = element;

  }

​

  // 删除链表某一项

  this.removeAt = function (position) {

​

    if (-1 < position && position < length) {

      if (position == 0) {

        var c = head;

        head = c.next;

      } else {

        var c = head;  //当前表

        var p = null;  //前一个表

        var index = 0;  //用来记录链表的第几项

        while (index < position) { //当index小于position的时候说明还没有走到需要添加位置的下标,需要重复执行并判断

          p = c; // 把当前的赋值给前一个

          c = c.next;  //把当前的next赋值给当前的表

          index++;

        }

        // 循环退出就相当于 index == position,说明要添加到当前index的位置。删除的话是需要在上一个表的next == 当前表的next(直接跳过当前表)

        p.next = c.next

      }

      length--

      return c

    }

  }

}

var l = new LinkedList();

l.append(1)

l.append(2)

l.append(3)

l.inster(2, "p")

返回某一元素的下标(如indexOf)

var LinkedList = function () {

  // 链表头

  var head = null;

  // 链表长度

  var length = 0;

  // 辅助类:节点

  var Node = function (element) {

    this.next = null;

    this.element = element;

  }

​

  // 返回某一元素的下标

  this.indexOf = function (element) {

​

    var c = head;   //当前表

    var index = 0;  //当前下标

    while (c.next) {

      if (c.element == element) {

        return index

      }

      index++

      c = c.next

    }

  }

​

​

var l = new LinkedList();

l.append(1)

l.append(2)

l.append(3)

l.inster(2, "p")

删除某一元素(复用removeAt和indexOf)

var LinkedList = function () {

  // 链表头

  var head = null;

  // 链表长度

  var length = 0;

  // 辅助类:节点

  var Node = function (element) {

    this.next = null;

    this.element = element;

  }

  // 删除某一元素

  this.romove = function (element) {

    return this.removeAt(this.indexOf(element))

  }

  // 检查链表头

  this.getHead = function () {

    return head;

  }

}

var l = new LinkedList();

l.append(1)

l.append(2)

l.append(3)

l.inster(2, "p")

判空,长度

var LinkedList = function () {

  // 链表头

  var head = null;

  // 链表长度

  var length = 0;

  // 辅助类:节点

  var Node = function (element) {

    this.next = null;

    this.element = element;

  }

    // isEmpty 检查链表是否为空

  this.isEmpty = function () {

    return items.length == 0

  }

  // size 检查链表元素个数

  this.size = function () {

    return items.length

  }

  // 检查链表头

  this.getHead = function () {

    return head;

  }

}

var l = new LinkedList();

l.append(1)

l.append(2)

l.append(3)

l.inster(2, "p")
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值