【数据结构】链表 用JavaScript实现

链表概念

链表:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

头结点:在单链表第一个元素结点之前设置的一个节点,数据域可以不存任何信息,指针域指向单链表第一个元素的结点。头结点不是链表必要元素。

头指针:指向单链表的第一个结点的指针,如果单链表有头结点,则头指针指向头结点,如果单链表没有头结点,则头指针指向第一个首元结点。头指针不能为空,头指针是链表的需要元素。

首元结点:单链表中第一个有数据元素的结点。如果单链表有头结点,则首元结点为头结点的下一个结点,如果单链表没有头结点,则首元结点为单链表的第一个结点。
在这里插入图片描述

单链表的实现

/* 定义单向链表结点类 */
class Node{
    constructor(data){
        this.data = data;    //结点的数据域(数据成员)
        this.next = null;    //结点的指针域(指针成员)
    }
}

/* 定义单向链表类 */
class SingleLinked{
    constructor(){  //初始化链表
        this.size = 0;  //记录链表结点个数,开始时链表结点个数为0
        this.head = new Node('head');   //链表头指针:记录链表的起始地址
    }

    //获取链表的长度
    getLength(){
        return this.size;
    }

    //判断链表是否为空
    isEmpty(){
        if(this.size === 0){
            return '链表为空';
        }else{
            return '链表非空';
        }
    }

    //遍历链表
    displayList(){
        var list = '';
        var currentNode = this.head;//指向链表的头指针
        while(currentNode){
            list += currentNode.data;
            currentNode = currentNode.next;//让指针指向当前节点的下一个节点
            if(currentNode){
                list += '->';
            }
        }
        return list;
    }

    //获取链表的最后一个节点
    findLast(){
        var currentNode = this.head;
        while(currentNode){
            currentNode = currentNode.next;
        }
        return currentNode;
    }

    //采用尾插法给链表插入元素
    appendNode(element){
        var currentNode = this.findLast();//找到当前链表的最后一个节点
        var newNode = new Node(Element);//创建一个新节点

        currentNode.next = newNode;
        newNode.next = null;

        this.size++;//链表的长度加1
    }

    //删除一个节点
    delete(element){
        var currentNode =this.head;
        while(currentNode.next.data!=element){
            currentNode = currentNode.next;
        }
        currentNode.next = currentNode.next.next;
        this.size--;
    }
    
}

双向链表的实现

//结点类
class Node{
    constructor(data){
        this.data = data;//结点的数据域
        this.prev = null;//指针域:指向当前结点的上一个结点
        this.next = null;//指针域:指向当前结点的下一个结点
    }
}

//双向链表类
class DoubleLinkList{
    constructor(){
        this.size = 0;//双向链表长度
        this.head = new Node('head');
        this.currNode = '';//当前节点指针
    }

    //判断链表是否为空
    isEmpty(){
        return this.size ===0;
    }

    //获取单链表的长度
    getLength(){
        return this.size;
    }

    //显示当前节点
    showNode(){
        console.log(thi.currNode.data);
    }

    //顺序遍历链表
    displayList(){
        let str = '';
        let currentNode = this.head;
        while(currentNode){//当前结点存在时
            str += currentNode.data;
            currentNode = currentNode.next;
            if(currentNode){
                str += '--->';
            }
        }
        return str;
    }

    //倒序遍历链表
    lastDisplayList(){
        let str = ''
        let currentNode = this.findLast();
        while(currentNode){
            str += currentNode.data;
            currentNode = currentNode.prev;
            if(currentNode){
                str += '--->';
            }
        }
        return str;
    }

    //查找某一个元素
    findNode(element){
        let currentNode = this.head;
        while(currentNode && (currentNode.data != element)){
            currentNode = currentNode.next;
        }
        return currentNode;
    }

     //获取最后一个结点
     findLast(){
        let currentNode = this.head;
        while(currentNode.next){
            currentNode = currentNode.next;
        }
        return currentNode;
    }

    //添加元素  头插法:在head结点后添加结点
    headAppend(element){
        let newNode = new Node(element);//创建一个新结点
        /* 先让待插入的结点与给定结点之外的结点相连,再与给定结点相连 */
        newNode.next = this.head.next;
        this.head.next.prev = newNode;       
        newNode.prev = this.head;
        this.head.next = newNode;
        this.size++;
    }

   //添加元素  尾插法
   append(element){
    let currentNode = this.findLast();
    let newNode = new Node(element);
    currentNode.next = newNode;
    newNode.prev = currentNode;
    newNode.next = null;
    this.size++;
   }

   //添加元素 插入结点,将element值插入到data值之后
   insertNextNode(data,element){
        let currentNode = this.findNode(data);
        if(!currentNode){//如果data结点不存在
            return;
        }
        let newNode = new Node(element);

        newNode.next = currentNode.next;
        currentNode.next.prev = newNode;
        newNode.prev = currentNode;
        currentNode.next = newNode;
        this.size++;
   }

   //添加元素 插入结点,将element值插入到data值之前
   insertpreNode(data,element){
        let currentNode = this.findNode(data);
        if(!currentNode){
            return;
        }
        let newNode = new Node(element);

        newNode.prev = currentNode.prev;
        currentNode.prev.next = newNode;
        newNode.next = currentNode;
        currentNode.prev = newNode;
        this.size++;
    }

    //删除指定节点
    deleteNode(element){
        let currentNode = this.findNode(element);
        if(currentNode.next === null){//要删除的结点为链表的最后一个节点
            currentNode.prev.next = null;
        }else{
            currentNode.prev.next = currentNode.next;
            currentNode.next.prev = currentNode.prev;
        }
        this.size--;
    }
}
//创建一个空双向链表
let doubleList = new DoubleLinkList()

//判断链表是否为空
console.log(doubleList.isEmpty())   //true

//尾插法依次插入数组中的元素
let arr = [1,3,5];
for(let i=0;i<arr.length;i++){
    doubleList.append(arr[i]);
}

//遍历双向链表
console.log(doubleList.displayList());  //head--->1--->3--->5

//指定结点后插入新结点
doubleList.insertNextNode(3,4);  //head--->1--->3--->4--->5

//指定结点前插入新结点
doubleList.insertpreNode(3,2);  //head--->1--->2--->3--->4--->5

//删除指定结点
doubleList.deleteNode(5);   //head--->1--->2--->3--->4

//前插法 在头元素后插入结点
doubleList.headAppend(100); //head--->100--->1--->2--->3--->4
doubleList.headAppend(20);  //head--->20--->100--->1--->2--->3--->4

//倒序遍历
console.log(doubleList.lastDisplayList());  //4--->3--->2--->1--->100--->20--->head
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南栀~zmt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值