当前位置: 首页 > article >正文

谈谈前端对链表的理解

概念

链表是一种常见的基础数据结构,它由一系列节点(Node)组成,用于存储一连串的数据。

class ListNode {
      val: number
      next: ListNode | null
      constructor(val?: number, next?: ListNode | null) {
          this.val = (val===undefined ? 0 : val)
          this.next = (next===undefined ? null : next)
      }
}

前端角度理解概念

将链表比作前端开发中的DOM(文档对象模型)树。
链表的每个节点就像是一个DOM元素。每个节点通常包含两部分:

  1. 数据部分(data):就像DOM元素的内容或者属性,比如一个文本节点的内容或者一个元素的类名。
  2. 指针部分(next):就像DOM元素的childNodes属性或者nextSibling属性,指向下一个节点。

链表的特点

  • 动态大小: 链表的大小不是固定的,可以随时添加或者删除节点,就像随时在DOM中添加或移除元素一样。

  • 顺序访问:链表的访问必须按顺序访问,不能直接访问中间的节点,需要从头部开始遍历,就像在DOM中,想要访问一个深层嵌套的元素,需要从根元素开始遍历。

  • 内存分配:
    链表的节点可以分散在内存中,它们不必连续存储,与数组不同,数组的元素必须连续存储。就好像DOM元素可以分布在HTML文档的不同位置。

链表与数组的不同

链表与数组在很多方面相似,但也有一些关键的区别:

  • 链表: 大小动态,元素不连续存储,只能顺序访问元素。
  • 数组: 具有固定的大小,元素连续存储在内存中,可以通过索引直接访问任何元素。
    链表的基础操作,代码如下:

class ListNode{
    constructor(value) {
        this.value = value;
        this.next = null;
    }
}

let head = new ListNode(1)
head.next = new ListNode(2)
head.next.next = new ListNode(3)
head.next.next.next = new ListNode(4)
head.next.next.next.next = new ListNode(5)

// 遍历打印每一个节点
let current = head;
while(current !== null) {
    console.log(current.value)// 1 2 3 4 5
    current = current.next
}

// 新增节点
let newNode = new ListNode(6)
current = head;
while(current.next !== null) {
    current = current.next
}
current.next = newNode


// 删除值为3的节点
current = head;
while(current.next !== null) {
    if(current.next.value === 3) {
        current.next = current.next.next
        break;
    }
    current = current.next
}

数组的基本操作,代码如下:

let array = [1, 2, 3]
console.log(array[2])// 3

array[2] = 6;
console.log(array)// [ 1, 2, 6 ]

array.push(8)
console.log(array)// [ 1, 2, 6, 8 ]

array.pop()
console.log(array)// [ 1, 2, 6 ]

从代码示例上展示了链表和数组在操作上的主要区别:

  • 数组通过索引直接访问元素,而链表需要从头开始遍历。
  • 数组的大小是固定的,而链表的大小是动态的,可以根据需要添加和删除节点。
  • 数组元素在内存中是连续存储的,链表元素则可能分散在内存中。

链表的经典案例:两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
代码实现:

class ListNode {
	val: number
	next: ListNode | null
	constructor(val?: number, next?: ListNode | null) {
		this.val = (val === undefined ? 0 : val)
		this.next = (next === undefined ? null : next)
	}
}

function addTwoNumbers(l1: ListNode | null, l2 : ListNode | null): ListNode | null {
	let dummy: ListNode = new ListNode(0)
	let current: ListNode = dummy;
	let carry: number = 0;
	while(l1 !== null || l2 !== null || carry !== 0) {
		// 计算当前位的和以及进位
		let val1: number = l1 ? l1.val : 0;
		let val2: number = l2 ? l2.val : 0;
		let sum_val: number = val1 + val2 + carry;
		carry = Math.floor(sum_val / 10)
		// 将当前和的个位数添加到结果链表中
		current.next = new ListNode(sum_val % 10);
		current = current.next;
		
		 // 移动链表指针
		if(l1) l1 = l1.next;
		if(l2) l2 = l2.next;
	}
	return dummy.next;
}

http://www.kler.cn/a/457094.html

相关文章:

  • Kinova在开源家庭服务机器人TidyBot++研究里大展身手
  • C#实验室信息系统源码,检验流程信息化LIS系统
  • Spring创建异步线程池方式
  • Linux 安装rpm
  • Android图形绘制之Shapes包详解
  • 关于Mysql表结构的元数据锁
  • ElasticSearch 统计分析全攻略
  • 数据结构课程设计/校园导游程序及通信线路设计 #2
  • P1588 [USACO07OPEN] Catch That Cow S 洛谷 BFS-最短路思想
  • Leetcode 283-移动零
  • FPGA抗单粒子容错的方法
  • 【信息系统项目管理师】高分论文:论信息系统项目的资源管理(阳光信访工作平台)
  • 国家发改委低空经济发展司亮相,CES Asia 2025低空经济展区受关注
  • flask后端开发(5):jinjia中if、for控制语句
  • Erlang语言的数据结构
  • c++入门——c++输入cin和输出cout的简单使用
  • Pandas04
  • 如何测试模型推理性能:从零开始的Python指南
  • 32位MCU主控智能电表方案
  • Linux下编译安装libMesh