JavaScript链表的实现

Posted 遥岑.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript链表的实现相关的知识,希望对你有一定的参考价值。

链表

链表概念

链表:数据的一种存储结构,一个链表包含若干个结点,每个结点至少包含一个数据域和一个指针域,指针域指向下一个结点。
结点:数据元素的存储映像,由存放数据元素的数据域和存放后继结点地址的指针域组成。
特点:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着,这些数据元素可以存在内存未被占用的任意位置。

头结点、头指针、首元结点的区别
区别

  • 头结点: 在单链表第一个元素结点之前设置的一个结点, 数据域可以不存任何信息,指针域指向单链表第一个元素的结点。头结点不是链表的必要元素
  • 头指针: 指向单链表的第一个结点的指针, 如果单链表有头结点,则头指针指向头结点,如果单链表没有头结点,则头指针指向第一个首元结点。头指针不能为空,头指针是链表的必要元素。
  • 首元结点:单链表中第一个有数据元素的结点。如果单链表有头结点,则首元结点为头结点的下一个结点,如果单链表没有头结点,则首元结点就是单链表的第一个结点

链表的基础操作

  • 获取链表长度
  • 判断链表是否为空
  • 遍历链表
  • 查找元素
  • 添加元素
  • 删除元素

单链表的实现

//定义节点类
class Node
{
    constructor(data)
    {
        this.data = data    //节点的数据域(数据成员)
        this.next = null    //节点的指针域(指针成员)
    }
}

//定义单向链表类
class SingleLinked
{
    constructor()
    {
        this.size = 0  //记录链表中的节点个数
        this.head = new Node('head')   //是链表的头指针,记录链表的起始地址
        this.currentNode = ''   //用来记录当前节点
    }

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

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

    //遍历链表:不重复访问链表中的每个节点
    displayList()
    {
        var list = ''
        var currentNode = this.head  //指向链表的头指针
        while(currentNode)  //若当前节点不为空 
        {
            list += currentNode.data
            currentNode = currentNode.next  //让指针指向当前节点的下一个节点
            if(currentNode)
            {
                list += '->'
            }
        }
        console.log(list)
    }

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

    //在单链表的尾部添加元素
    appendNode(element)
    {
        var currNode = this.findLast()   //找到链表的最后一个节点
        var newNode = new Node(element)  //创建一个新的节点
        currNode.next = newNode
        newNode.next = null
        this.size++    //链表长度+1
    }

    //删除一个节点
    delete(element)
    {
        var currNode = this.head
        while(currNode.next.data!=element)
        {
            currNode = currNode.next
        }
        currNode.next = currNode.next.next
        this.size--
    }
}
  • 注意:在单链表中间插入元素时注意连接结点的顺序

双向链表的实现

//定义一个节点类
class Node 
{
    constructor(data)
    {
        this.data = data
        this.next = null
        this.previous = null
    }
}

//双向链表类
class DoubleLinked
{
    constructor()
    {
        this.size = 0
        this.head = new Node('head')
        this.currentCode = ''  //当前节点指针
    }

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

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

    //显示当前节点
    showNode()
    {
        console.log(this.currentNode.data)
    } 

    //遍历
    displayList()
    {
        var str = ''
        var currentNode = this.head
        while(currentNode)
        {
            str += currentNode.data
            currentNode = currentNode.next
            if(currentNode) 
            {
                str += '-->'
            }
        }
        return str
    }

    //倒序遍历链表
    lastDisplay()
    {
        var str = ''
        var currentNode = this.findLast()
        while(currentNode)
        {
            str += currentNode.data
            currentNode = currentNode.previous
            if(currentNode)
            {
                str += '-->'
            }
        }
        return str
    }

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

    //在data后插入节点
    insertNode(data,element)
    {
        var currentNode = this.findNode(data)
        //如果data不存在
        if(!currentNode)
        {
            return
        }
        var newNode = new Node(element)
        newNode.previous = currentNode
        newNode.next = currentNode.next
        currentNode.next.previous = newNode
        currentNode.next = newNode
        this.size++
    }

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

    //尾部添加节点
    appendNode(data)
    {
        var currentNode = this.findLast()
        var newNode = new Node(data)
        currentNode.next = newNode
        newNode.next = null
        newNode.previous = currentNode
        this.size++
    }

    //删除一个节点
    deleteNode(data)
    {
        var currentNode = this.findNode(data)
        if(currentNode.next == null) //如果删除的节点是最后一个节点
        {
            currentNode.previous.next = null
        }
        else
        {
            currentNode.previous.next = currentNode.next
            currentNode.next.previous = currentNode.previous
        }
        this.size--
    }
}
  • 注意:单链表插入操作时连接结点的顺序
  • 先连接新结点的前驱和后继,再连接后结点的前驱,最后连接前结点的后继
newNode.previous = currentNode
newNode.next = currentNode.next
currentNode.next.previous = newNode
currentNode.next = newNode

以上是关于JavaScript链表的实现的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript数据结构——链表的实现

JavaScript 实现链表的操作

JavaScript 实现双向链表的操作

NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段

JavaScript笔试题(js高级代码片段)

C语言反转单向链表的代码