前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript实现一个链表结构源码分享

JavaScript实现一个链表结构源码分享

作者头像
何处锦绣不灰堆
发布2021-02-02 16:54:25
5370
发布2021-02-02 16:54:25
举报
文章被收录于专栏:农历七月廿一
写在前面

刷题的时候看到一个关于链表的题目,写了一会发现写不出来,所以干脆就将链表的知识使用js重现一遍,这里写一个js实现的链表。

链表结构介绍

没有写代码之前呢我们先简单的说一下什么是链表,我们都知道,在很多的数据结构中,有序的结构我们比较熟悉是数组,数组和链表还有一些不同,数组是内存空间按照挨个顺序来的,那么链表的话是可以不按照顺序来的,链表结构是当前元素(data),下一个元素(next),上一个元素(pre),第一位是head,最后一位的next指向null 链表分为下面几种常见的!

  • 单向链表

每一个节点的next都指向下一个节点,最后一个节点的next指向的是null

  • 双向链表

每一个节点都有一个next和pre,相互指向就形成了双向链表

  • 单向循环链表

单向链表的最后一个节点指向了该链表的第一个节点

  • 双向循环链表

第一个节点的pre指向了该链表的最后一个,该链表的最后一个next指向了第一个节点

  • 环形链表

任意两个节点之间形成了pre和next相互指向的情况,都可以叫做环形链表

源码实现

我们使用js实现一个简单的单向链表,提供一种思路出来

代码语言:javascript
复制
/**
 * @author clearlove
 * @class Node   当前节点
 * @class LinkedList 当前链表
 * @function appendNode  添加节点
 * @function getNode  根据索引查找节点元素
 * @function appendAt  根据位置插入节点
 * @function remove    移除节点
 * @function searchCurrIndexof 根据元素查找索引
 * @function sort  链表排序
 * @function linkedToArr 链表转为数组
 * @function arrToLinked 数组转为链表
 * 
 */
//声明一个Node节点
class Node {
    constructor(data) {
        this.data = data
        this.next = null
    }
}
class LinkedList {
    constructor() {
            this.size = 0
            this.head = null
        }
        //增加一个节点
    appendNode(tempNode) {
            let node = new Node(tempNode)
                //判断一下当前的链表是不是一个空的 this.head === null 或者是当前的链表的长度为0
            if (this.head === null) {
                //如果是空的,那么我们的当前的节点就是第一位
                this.head = node
            } else {
                //如果不是空的,我们要做的是,将当前的节点追加到当前链表的最后一位的后面,
                //也就是我们首先需要找到当前链表的最后一位,让后将他的next给当前的node
                let current = this.getNode(this.size - 1) //找到当前的最后一位
                current.next = node
            }
            //链表的长度追加
            this.size++
        }
        //找到当前一个 的节点
    getNode(index) {
            if (index < 0 || index >= this.size) {
                throw new Error('error')
            }
            let current = this.head
            for (let i = 0; i < index; i++) {
                current = current.next
            }
            return current
        }
        //按照指定位置增加
    appendAt(position, tempNode) {
            //首先要知道当前的位置是不是小于0  或者是大于当前链表的长度
            if (position < 0 || position > this.size) {
                throw new Error('error')
            }
            let node = new Node(tempNode)
            if (position === 0) {
                //从第一位开始追加,说明我们需要将当前的node的下一位等于之前的第一位,再将head等于当前的node
                node.next = this.head
                this.head = node
            } else {
                //如果当前位置插入一个节点,需要做的就是将插入位置的之前节点的位置找到即可
                let pre = this.getNode(position - 1)
                node.next = pre.next
                pre.next = node
            }
            this.size++
        }
        //删除指定节点的元素
    remove(position) {
        //首先要知道当前的位置是不是小于0  或者是大于当前链表的长度
        if (position < 0 || position > this.size) {
            throw new Error('error')
        }
        //先将当前头部节点找到
        let currentHead = this.head
        if (position === 0) {
            //说明当前我要删除的是第一位的节点,那么更新头部的信息为之前的节点的next
            this.head = currentHead.next
        } else {
            //如果链表中的某一个节点的删除的时候,我们需要做的就是找到删除的节点的前一个节点,然后将前一个节点的next等于被删除的节点的next
            let pre = this.getNode(position - 1)
            currentHead = pre.next
            pre.next = currentHead.next
        }
        this.size--
    }

    //按照指定元素的索引
    searchCurrIndexof(tempNode) {
            //从头部开始找
            let current = this.head
            for (let i = 1; i < this.size; i++) {
                if (current.data === tempNode) {
                    return i
                }
                current = current.next
            }
            //完全找不到的时候我们直接返回-1或者false都可以
            return -1
        }
        //排序
    sort(tempLinked) {
            let tempArr = this.linkedToArr(tempLinked)
            let maxL = tempArr.length - 1
            for (let j = 0; j < maxL; ++j) {
                let flag = true
                for (let i = 0; i < maxL - j; ++i) {
                    if (tempArr[i] > tempArr[i + 1]) {
                        let temp = tempArr[i]
                        tempArr[i] = tempArr[i + 1]
                        tempArr[i + 1] = temp
                        flag = false
                    }
                }
                if (flag) {
                    break
                }
            }
            return this.arrToLinked(tempArr)
        }
        //链表转为数组
    linkedToArr(tempLinked) {
            let result = []
            let headNode = tempLinked.head
            while (headNode) {
                result.push(headNode.data)
                headNode = headNode.next
            }
            return result
        }
        //数组转为链表
    arrToLinked(tempArr) {
        let ll = new LinkedList()
        tempArr.map(res => {
            ll.appendNode(res)
        })
        return ll
    }
}
测试结果
代码语言:javascript
复制
//测试
let ll = new LinkedList()
ll.appendNode(1)
ll.appendNode(2)
ll.appendNode(3)
ll.appendAt(3, 'jim')
ll.appendNode(4)
//这里是为了将结果全部展开,所以序列化一下
console.log(JSON.stringify(ll))
最后

链表可能说我们平常用的不是很多,但是这是一种很好的思路,我觉得还是很有必要了解和学习一下的,毕竟很多的数据结构都是从一些简单的结构进行开展思维的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • 链表结构介绍
  • 源码实现
  • 测试结果
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档