JS实现数据结构(四):双向链表

本文探讨了双向链表的概念,它允许从头到尾或从尾到头进行遍历。详细介绍了双向链表的数据结构,并列出了其关键操作,如添加、插入、获取、更新、删除元素以及判断是否为空、获取元素数量等方法。此外,还提供了正向和反向遍历链表的字符串表示方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 单向链表只能从从遍历到尾,缺点是可以轻松到达下一个节点,但是很难回到上一个节点
  • 双向链表可以从头遍历到尾,也可以从尾遍历到头,一个节点既有向前的引用,也有向后的引用
  • 双向链表结构截屏2020-11-18 上午10.44.24- 双向链表方法
    • append(element):向列表尾部添加一个新的项
    • insert(position,element):向列表的特定位置插入一个新的项。
    • get(position):获取对应位置的元素
    • indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1。
    • update(position,element):修改某个位置的元素
    • removeAt(position):从列表的特定位置移除一项。
    • remove(element):从列表中移除一项。
    • isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false.
    • size():返回链表包含的元素个数。与数组的length属性类似。
    • toString():由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值。
    • forwardString():返回正向遍历的节点字符串形式
    • backwordString():返回反向遍历的节点字符串形式
  • 封装双向链表
function DoubleLinkedList(){
  //内部类:节点类
  function Node(data){
    this.data = data;
    this.pre =  null;
    this.next = null;
  }
  //属性
  this.head = null;
  this.tail = null;
  this.length = 0 ;
  
  //1.append()
  DoubleLinkedList.prototype.append = function(data){
    var newNode = new Node(data);
    
    if(this.length === 0){
      this.head = newNode;
      this.tail = newNode;
    }else{
      newNode.pre = this.tail;
      this.tail.next = newNode;
      this.tail = newNode;
    }
    this.length += 1;
  }
  
  //2.insert()
  DoubleLinkedList.prototype.insert = function(position,data){
    //越界判断
    if(position < 0 || position > this.lengh) return false;
    //创建新节点
    var newNode = new Node(data);
    //定位
    //判断链表是否为空
    if(this.length === 0){
      this.head = newNode;
      this.tail = newNode;
    }else{
      if(position === 0){
        this.head.pre = newNode;
        newNode.next = this.head;
        this.head = newNode;
      }else if(position = this.length){
        newNode.pre = this.tail;
        this.tail.next = newNode;
        this.tail = newNode;
      }else{
        var current = this.head;
        var index = 0
        while(index++ < position){
          current = current.next;
        }
        newNode.next = current;
        newNode.pre = current.pre;
        current.pre.next = newNode;
        current.pre = newNode;
      }
    }
    this.length += 1;
    return true;
  }
  
  //3.get()
  DoubleLinkedList.prototype.get = function(position){
  	if(position < 0 || position >=this.length) return false;
    var current = this.head;
    var index = 0;
    while(index++ < position){
      current = current.next;
    }
    return current.data;
  }
  
   //4.indexOf()
  DoubleLinkedList.prototype.indexOf = function(data){
    var current = this.head;
    var index = 0;
    while(current){
      if(current.data === data){
        return index;
      }else{
        current = current.next;
        index++;
      }
    }
    return -1;
  }
  
  //5.update()
  DoubleLinkedList.prototype.update = function(position){
  	if(position < 0 || position >=this.length) return false;
    var current = this.head;
    var index = 0;
    while(index++ < position){
      current = current.next;
    }
    current.data = data;
  }
  
  //6.removeAt()
  DoubleLinkedList.prototype.removeAt= function(position){
  	if(position < 0 || position >=this.length) return null;
    
    var current = this.head;
    var index = 0 ;
    if(this.length === 1){
      this.head = null;
      this.tail = null;
    }else{
      if(position === 0){
        this.head.next = null;
        this.head = this.head.next;
      }else if(position === this.length-1){
        current = this.tail;
        this.tail.pre.next = null;
        this.tail = this.tail.pre;
      }else{
        while(index++ < position){
          current = current.next;
        }
        current.pre.next = current.next;
        current.next.pre = current.pre;
      }
  	}
    this.length -= 1;
    return current.data
  }
  
  //7.remove()
  DoubleLinkedList.prototype.remove = function(){
  	var index = this.indexOf(data);
    return this.removeAt(index);
  }
  
  //8.isEmpty()
  DoubleLinkedList.prototype.ieEmpty = function(){
    return this.length === 0 ;
  }
  
  //9.size()
   DoubleLinkedList.prototype.size = function(){
    return this.length;
  }
  
  //10.获取链表第一个元素
   DoubleLinkedList.prototype.getHead = function(){
    return this.head.data;
  }
  
  //11.获取链表最后一个元素
   DoubleLinkedList.prototype.getTail = function(){
    return this.tail.data;
  }
  
  //12.toString()
  DoubleLinkedList.prototype.toString = function(){
    return this.backwardString();
  }
  
  //13.toString()
  DoubleLinkedList.prototype.toString = function(){
    return this.backwardString();
  }
  
  //14.forwardString()
  DoubleLinkedList.prototype.forwardString = function(){
    var current = this.tail;
    var resultString = null;
    while(current){
      resultString += current.data + " ";
      current = current.pre
    }
    return resultString;
  }
  //15.backwardString()
  DoubleLinkedList.prototype.backwardString = function(){
  	var current = this.head;
    var resultString = '';
    while(current){
      resultString += current.data + " ";
      current =current.next;
    }
    return resultString;
  }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值