"- 제 3 판 자바 스크립트 데이터 구조와 알고리즘을 학습"- 다시 읽기 제 6 장 목록 (A)

시 감안할 때

伤情最是晚凉天,憔悴厮人不堪言;
邀酒摧肠三杯醉.寻香惊梦五更寒。
钗头凤斜卿有泪,荼蘼花了我无缘;
小楼寂寞新雨月.也难如钩也难圆。

머리말

목록뿐만 아니라 공정하고 목록의 원칙의 실현 -이 장에서는이 장에서는 데이터 구조에 대해 주로, 기사의 "자바 스크립트 데이터 구조와 알고리즘을 학습"시리즈를 다시 읽어.

명부

목록 , 왜이 데이터 구조를 가지고? 물론, 모든 이유가 일어났다!

배열 - 가장 일반적이고 편리한 데이터 구조, 그러나 , 우리가 삽입하거나 우리가 요소를 이동해야하기 때문에 비용이 많이 드는 시작 또는 중간 배열에서 항목을 이동할 때.

목록은 요소의 집합 순서화 저장됩니다. 리스트 메모리 소자를 연속적으로 배치되지 않고, 각 원소 자체가 기억 소자로 구성하고, 노드 기준 (포인터 또는 링크) 조성물의 요소를 가리키는.

이주의, 링 최대의 초점이다, 인터뷰를 테스트해야!

링크리스트의 구현

구조 및 대응하는 메소드를 대략 목록을 달성한다 : 더 상세하게 논리를 구현하는 코드를 표시 소자의 삽입, 제거, 액세스리스트 길이 질의 요소가 비어 등 ....

더 복잡한 데이터 구조 나 자신 ...의 정신을 이해하는 데 관심을 ...

/**
 * 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 개방형 플랫폼의 최고 프런트 엔드 포위 사자. 당신과 얘기 큰 프런트 엔드, 프런트 엔드 공유 시스템 아키텍처 프레임 워크의 구현 원리, 최신 및 가장 효율적인 기술을 연습!

를 눌러 스캔 코드 관련, 더 잘 생기고 더 아름다운 요! 어떤 대중의 관심 후 동생 뭔가 후 형제 요 함께 깊이있는 교류를 계속할 수 말할 수 있습니다!

후 동생 뭔가 말을

추천

출처www.cnblogs.com/justbecoder/p/11410022.html