• 数据结构——单向链表


    一、链表

    概念:

    • 用于存储数据的线性结构  可存储多个元素
    • 链表中的元素在内存中不必是连续的空间

    • 链表的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(有些语言称为指针或者链接)组成.

    优缺点:

    • 优点

      • 内存空间不是比是连续的. 可以充分利用计算机的内存. 实现灵活的内存动态管理.

      • 链表不必在创建时就确定大小, 并且大小可以无限的延伸下去.

      • 链表在插入和删除数据时, 时间复杂度可以达到O(1). 相对数组效率高很多.

    • 缺点

      • 链表访问任何一个位置的元素时, 都需要从头开始访问.(无法跳过第一个元素访问任何一个元素).

      • 无法通过下标直接访问元素, 需要从头一个个访问, 直到找到对应的位置.

    单向链表的结构:

    二、程序封装单向链表

    1.创建链表类:

    1. //封装节点的结构
    2. class Lnode {
    3. constructor(data) {
    4. //保存每个节点信息
    5. this.data = data
    6. this.next = null
    7. }
    8. }
    9. // 封装链表的结构
    10. class LinkList {
    11. constructor() {
    12. //链表中的属性
    13. this.length = 0 // 链表的长度
    14. this.head = null // 链表的第一个节点
    15. }

    2.链表操作 :

    链表的常见操作:

    • append(element):向列表尾部添加一个新的项

    • insert(position, element):向列表的特定位置插入一个新的项

    • remove(element):从列表中移除一项

    • indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1

    • removeAt(position):从列表的特定位置移除一项

    • isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false

    • size():返回链表包含的元素个数。与数组的length属性类似

    • toString():由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值

     链表中的方法:

    (1) append(element):向列表尾部添加一个新的节点

    1. append(ele) {
    2. //创建一个新节点
    3. let newnode = new Lnode(ele)
    4. //链表为空时 新添加的节点为唯一的节点 头部直接指向新节点
    5. if (this.head == null) {
    6. this.head = newnode
    7. } else {
    8. //链表不为空时 向最后一个节点后面追加新节点
    9. //定义变量, 保存当前找到的节点
    10. let current = this.head
    11. while (current.next != null) {
    12. current = current.next
    13. }
    14. //current表示最后一个节点 将最后节点的next指向新节点 建立连接
    15. current.next = newnode
    16. }
    17. //链表长度加1
    18. this.length++
    19. }

    (2)insert(position, element):向列表的特定位置插入一个新的节点

    1. insert(position, ele) {
    2. //判断位置是否合法(越界问题)
    3. if (position < 0 || position > this.length || Number.isInteger(position)) {
    4. return false
    5. }
    6. let newnode = new Lnode(ele)
    7. //1.在头部插入
    8. if (position == 0) {
    9. if (this.head == null) {
    10. this.head = newnode
    11. } else {
    12. newnode.next = this.head
    13. this.head = newnode
    14. }
    15. this.length++
    16. } else if (position == this.length) {
    17. //2.在尾部插入
    18. this.append(ele)
    19. } else {
    20. //3.在中间位置插入
    21. /*思路:
    22. 找到要插入的位置的前一个节点 position-1
    23. 首先先将新节点连上去 新节点next=current.next
    24. 将前一个的指向重新指向新节点 current.next=newnode
    25. */
    26. let current = this.head
    27. let index = 0
    28. while (index < position - 1) {
    29. current = current.next
    30. index++
    31. }
    32. //while循环后的current就是前一个节点
    33. //新节点的next指向 指向后一个节点
    34. newnode.next = current.next
    35. //前一个节点的next指向 指向新节点
    36. current.next = newnode
    37. this.length++
    38. }
    39. }

    (3)removeAt(position):从列表的特定位置移除节点

    1. removeAt(position) {
    2. //判断位置是否合法(越界问题)
    3. if (position < 0 || position > this.length || Number.isInteger(position)) {
    4. return false
    5. }
    6. if (this.head == null) {
    7. return
    8. } else {
    9. //非空链表
    10. if (position == 0) {
    11. //移除头部
    12. this.head = this.head.next
    13. this.length--
    14. } else {
    15. //移除任意位置(包括末尾)
    16. let current = this.head,
    17. index = 0
    18. while (index < position - 1) {
    19. current = current.next
    20. index++
    21. }
    22. current.next = current.next.next
    23. }
    24. this.length--
    25. }
    26. }

    (4)indexOf(element):返回元素在列表中的索引  如果列表中没有该元素则返回-1

    1. indexOf(ele) {
    2. let current = this.head,
    3. index = 0
    4. while (index < this.length) {
    5. if (current.data == ele) {
    6. return index
    7. } else {
    8. current = current.next
    9. index++
    10. }
    11. }
    12. //找完了都没有
    13. return -1
    14. }

    (5)remove(element):从列表中移除一个节点

    1. remove(ele) {
    2. let index = this.indexOf(ele)
    3. return this.removeAt(index)
    4. }

    (6)toString(): 将链表中的数据链接为字符串

    1. toString() {
    2. let current = this.head(),
    3. index = 0,
    4. res = ""
    5. while (index < this.length) {
    6. res += "-" + current.data
    7. current = current.next
    8. index++
    9. }
    10. return res.slice(1)
    11. }

    (7)isEmpty():链表为空时返回true,链表长度大于0则返回false

    1. isEmpty() {
    2. return this.length == 0
    3. }

    (8)size():返回链表包含的元素个数。与数组的length属性类似

    1. size() {
    2. return this.length
    3. }
  • 相关阅读:
    如何分析一篇论文或者是期刊?
    uni-app canvas 签名
    完整数字华容道02:软件结构设计
    RK3568平台开发系列讲解(Linux系统篇)kernel config 配置解析
    dos2unix命令
    Day 94
    【CentOS】忘记root密码
    Windows之nslookup命令
    设置Domino服务器上的Web文件保护
    回顾C++
  • 原文地址:https://blog.csdn.net/qq_56668869/article/details/126480376