Js 单链表 实践

292 阅读1分钟

js 实现单链表

// 节点
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

// 链表
class LinkedList {
  constructor() {
    this.head = null;
    this.tail = this.head; // 开始的时候, 指向的是同一个地址
    this.length = 0;
  }

  // 顺序插入
  append(value) {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = newNode;
      this.tail = newNode;
    } else {
      this.tail.next = newNode;
      this.tail = newNode;
    }
    this.length++;
  }

  // 在链表头部插入
  prepend(value) {
    const newHead = new Node(value);
    newHead.next = this.head;
    this.head = newHead;
    this.length++;
  }

  // 在指定位置插入
  insert(value, index) {
    if (index >= this.length) {
      this.append(value);
    } else {
      const insetNode = new Node(value);
      const { prevNode, nextNode } = this.getPrevNextNode(index);
      prevNode.next = insetNode;
      insetNode.next = nextNode;
      this.length++;
    }
  }

  // 查找当前节点
  find(index) {
    let currNode = this.head;
    let flag = 0;
    while(flag < index - 1) {
      currNode = currNode.next;
      flag++;
    }
    return currNode;      
  }

  // 删除
  remove(index) {
    const { prevNode, nextNode } = this.getPrevNextNode(index);
    prevNode.next = nextNode;
  }
  
  // 反转
  reverse() {
    let previousNode = null;
    let currNode = this.head;
    while(currNode !== null) {
      let nextNode = currNode.next;
      currNode.next = previousNode;
      previousNode = currNode;
      currNode = nextNode;
    }
  }

  // 获取上一个和下一个结点
  getPrevNextNode(index) {
    let flag = 0;
    let prevNode = this.head;
    let nextNode = prevNode.next.next;
    while(flag < index - 1) {
      prevNode = prevNode.next;
      nextNode = prevNode.next;
      flag++;
    }
    return { prevNode, nextNode }
  }
}

const linkedList = new LinkedList();
linkedList.append(1);
linkedList.append(2);
linkedList.append(3);
linkedList.append(4);
linkedList.prepend(0);
console.log(linkedList.find(3))

LeetCode 链表相关的题型

一、链表的反转

  1. 反转链表:leetcode.cn/problems/UH…
    输入:[1, 2, 3, 4, 5] 输出:[5, 4, 3, 2, 1]

     /**
      * @param {ListNode} head
     * @return {ListNode}
     */
     var reverseList = function(head) {
       let prev = null;
       let curr = head;
       while(curr) {
         const next = curr.next;
         curr.next = prev;
         prev = curr;
         curr = next;
       }
       return prev;
     };
    
  2. 回文字符串:leetcode.cn/problems/aM… 输入: head = [1,2,3,3,2,1] 输出: true

    /**
      * Definition for singly-linked list.
     * function ListNode(val, next) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.next = (next===undefined ? null : next)
     * }
     */
     /**
     * @param {ListNode} head
     * @return {boolean}
     */
     var isPalindrome = function(head) {
         let arr = [];
         while (head !== null) {
             arr.push(head.val)
             head = head.next;
         }
         let res = true;
         for (let i = 0, j = arr.length - 1; i < j; ++i, --j) {
             if (arr[i] !== arr[j]) {
                 return false;
             }
         }
         return res;
     };