시 감안할 때
伤情最是晚凉天,憔悴厮人不堪言;
邀酒摧肠三杯醉.寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘;
小楼寂寞新雨月.也难如钩也难圆。
머리말
목록뿐만 아니라 공정하고 목록의 원칙의 실현 -이 장에서는이 장에서는 데이터 구조에 대해 주로, 기사의 "자바 스크립트 데이터 구조와 알고리즘을 학습"시리즈를 다시 읽어.
명부
목록 , 왜이 데이터 구조를 가지고? 물론, 모든 이유가 일어났다!
배열 - 가장 일반적이고 편리한 데이터 구조, 그러나 , 우리가 삽입하거나 우리가 요소를 이동해야하기 때문에 비용이 많이 드는 시작 또는 중간 배열에서 항목을 이동할 때.
목록은 요소의 집합 순서화 저장됩니다. 리스트 메모리 소자를 연속적으로 배치되지 않고, 각 원소 자체가 기억 소자로 구성하고, 노드 기준 (포인터 또는 링크) 조성물의 요소를 가리키는.
이주의, 링 최대의 초점이다, 인터뷰를 테스트해야!
링크리스트의 구현
구조 및 대응하는 메소드를 대략 목록을 달성한다 : 더 상세하게 논리를 구현하는 코드를 표시 소자의 삽입, 제거, 액세스리스트 길이 질의 요소가 비어 등 ....
더 복잡한 데이터 구조 나 자신 ...의 정신을 이해하는 데 관심을 ...
/**
* Node 节点类,用于生成自身节点与下一个元素的引用
*/
class Node {
constructor(element) {
this.element = element
this.next = undefined
}
}
/**
* defaultEquals() 用于比较两个非对象类的值是否相等
*/
function defaultEquals (a, b) {
return a === b
}
/**
* LinkedList 链表
* 特点:链表存储有序的元素集合,但元素在内存中并不连续存放。每个元素有一个存储元素本身的节点和一个指向下一个元素的引用
*/
class LinkedList {
constructor (equalsFn = defaultEquals) {
// 链表长度
this.count = 0
// 第一个元素引用
this.head = undefined
// 用于比较元素是否相等,默认为defaultEquals,允许传入自定义的函数来比较两个对象是否相等。
this.equalsFn = equalsFn
}
}
주 : 물체 희토류 원소를 비교할 때 equalsFn 파라미터는,이 두 값이 동일한 객체 비교 맞춤 방법을 통과 할 필요가있다.
푸시()
목록의 마지막에 요소를 추가
/**
* push() 添加元素到链表
* @param {*} element 待添加的元素
*/
push (element) {
let node = new Node(element)
let current
// 判断链表是否为空
if (this.head == null) {
this.head = node
} else {
// 查询最后的元素 - 特点 current.next == null
current = this.head
while (current.next != null) {
current = current.next
}
// 将最后元素的下一个元素引用指向node
current.next = node
}
this.count++
}
getElementAt ()
요소의 인덱스 위치를 취득
/**
* getElementAt() 返回索引位置元素
* @param {Number} index 索引位置
* @returns {*} node
*/
getElementAt (index) {
// 判断索引是否有效
if (index < 0 || index > this.count) {
return undefined
}
let node = this.head
for (let i = 0; i < index && node != null; i++) {
node = node.next
}
return node
}
끼워 넣다()
인덱스 위치에 임의의 요소를 삽입
/**
* insert() 在任意位置插入元素
* @param {*} element 待插入的元素
* @param {Number} index 指定的索引位置
* @returns {Boolean}
*/
insert (element, index) {
// 判断是否为合法index
if (index < 0 || index > this.count) {
return false
}
// 实例化节点
let node = new Node(element)
// 插入-第一个位置
if (index === 0) {
let current = this.head
node.next = current
this.head = node
} else {
// 查找到指定索引位置的前一个元素
let previous = this.getElementAt(index - 1)
let current = previous.next
// 将上一个元素的next引用指向当前新添加的node,将node的next引用指向current,则完成插入
previous.next = node
node.next = current
}
// 链表长度+1
this.count++
return true
}
RemoveAt을 ()
지정한 인덱스에서 요소를 제거합니다
로직 구현 : 그것은 제 경우리스트의 첫 번째 항목이, 다음 두 번째 요소는 점 this.head 수 있는지 여부를 결정하는 단계; 상기 제되지 다음 인덱스 인덱스가 이전 요소의 위치를 인덱스의 총수를 취득하는 경우, 및 다음 위치 인덱스 요소 current.next은 current.next을 가리킬 수 있습니다 previous.next합니다
/**
* removeAt() 移除指定位置的元素
* @param {Number} index
* @returns {*} element 移除的元素
*/
removeAt (index) {
// 判断是否是合法索引
if (index < 0 || index > this.count) {
return undefined
}
let current = this.head
// 考虑是否是链表第一项
if (index === 0) {
this.head = current.next
} else {
// 方法一、 使用for循环迭代获取指定索引位置的元素
// 用于获取上一位置元素
// let previous
// for (let i = 0; i < index; i++) {
// previous = current
// current = current.next
// }
// // 跳过当前元素,将上一个元素的next指向下一个元素
// previous.next = current.next
// 方法二、借助getElementAt()方法
// 查询该索引位置的上一个元素
let previous = this.getElementAt(index - 1)
// 跳过中间元素,将上一个元素的next指向下一个元素
current = previous.next
previous.next = current.next
}
this.count--
return current.element
}
같이 IndexOf ()
요소 쿼리의 인덱스 위치
로직 구현 :; 맞춤 방법의 객체 클래스 패스의 값이 항등 초간 비교 유의하는 것이 중요 반복적 인 요소를 각 소자와 타겟 요소를 비교하여 동등
/**
* indexOf() 查询元素的索引位置
* @param {*} element 待查询的元素
* @returns {Number} index 索引位置,不存在则返回-1
*/
indexOf (element) {
let current = this.head
for (let i = 0; i < this.count && current != null; i++) {
// 判断两个元素是否相同
if (this.equalsFn(element, current.element)) {
return i
}
current = current.next
}
return - 1
}
풀다()
지정된 요소를 제거
/**
* remove() 移除元素
* @param {*} element 待移除的元素
* @returns {*} element 移除的元素
*/
remove (element) {
// 获取索引位置
let index = this.indexOf(element)
// 移除指定索引位置的元素
return this.removeAt(index)
}
크기()
리스트의 길이를 가져옵니다
/**
* size() 返回链表长度
* @returns {Number} 链表长度
*/
size () {
return this.count
}
비었다()
목록이 비어 있는지 확인
/**
* isEmpty() 判断链表是否为空
* @returns {Boolean}
*/
isEmpty () {
return this.count === 0
}
getHead ()
목록의 첫 번째 요소를 가져옵니다
/**
* getHead() 获取链表首位元素
* @returns {*}
*/
getHead () {
if (this.head != null) {
return this.head.element
}
return undefined
}
명확한()
빈 목록
/**
* clear() 清空链表
*/
clear () {
this.count = 0
this.head = undefined
}
toString ()
문자열 처리 목록
/**
* toString() 链表字符串化展示
* @returns {String}
*/
toString () {
// 判断是否为空
if (this.isEmpty()) {
return ''
}
let objStr = `${this.head.element}`
let current = this.head.next
for (let i = 1; i < this.count; i++) {
objStr = `${objStr},${current.element}`
current = current.next
}
return objStr
}
목록을 사용하여
let linkedList = new LinkedList()
console.log(linkedList.isEmpty()) // true
// push 尾部压入元素
linkedList.push(15)
linkedList.push(20)
/*
LinkedList {
count: 2,
head: Node {
element: 15,
next: Node {
element: 20,
next: undefined
}
},
equalsFn: [Function: defaultEquals]
}
*/
console.log(linkedList)
console.log(linkedList.isEmpty()) // false
// getElementAt() 指定索引位置的元素
let node = linkedList.getElementAt(1)
console.log(node)
// insert() 任意索引位置插入元素
linkedList.insert(22, 1)
linkedList.insert(33, 1)
console.log(linkedList.toString()) // 15,33,22,20
// removeAt() 移除指定索引位置的元素
console.log(linkedList.removeAt(1)) // 33
// remove() 移除元素
console.log(linkedList.remove(15)) // 15
console.log(linkedList.toString()) // 22,20
console.log(linkedList.getHead()) // 22
console.log(linkedList.size()) // 2
console.log(linkedList.toString()) // 22,20
console.log(linkedList.isEmpty()) // false
linkedList.clear()
console.log(linkedList.isEmpty()) // true
다시 아래 : 목록이 개체 유형 값에 저장되어있는 경우, 자신을 비교 equalsFn 지정된 비교 함수를 통과해야합니다, 당신은 이유를 알고한다!
추신
그리고 후 오빠 오늘은 작은 파트너가 기억 같은 콘텐츠를 공유 할 수 있음을 收藏
, 그리고 转发
오른쪽 아래 버튼을 클릭 在看
추천 더 주니어 파트너 요, 메시지 교환의 많은에 오신 것을 환영합니다 ...
후 동생 뭔가는 기술, 후 동생의 느낌을 말할! Jingdong 개방형 플랫폼의 최고 프런트 엔드 포위 사자. 당신과 얘기 큰 프런트 엔드, 프런트 엔드 공유 시스템 아키텍처 프레임 워크의 구현 원리, 최신 및 가장 효율적인 기술을 연습!
를 눌러 스캔 코드 관련, 더 잘 생기고 더 아름다운 요! 어떤 대중의 관심 후 동생 뭔가 후 형제 요 함께 깊이있는 교류를 계속할 수 말할 수 있습니다!