数据结构与算法 - 单向链表

100 阅读2分钟

链表的介绍

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点;

方法

  1. append(element) 向列表尾部添加一个新的项
  2. insetr(position, element) 向列表的特定位置插入一个新的项
  3. get(position) 获取对应位置的元素
  4. indexOf(element) 返回元素在列表中的索引.如果列表中没有该元素则返回-1
  5. removeAt(position) 从列表特定的位置移除一项
  6. update(position, element) 修改某个位置的元素
  7. remove(element) 从列表中移除一项
  8. isEmpty() 如果列表中不包含任何元素,返回true,链表的长度大于0则返回false
  9. size() 返回列表包含元素的个数, 与数组的length类似

代码

class Node {
  element: any;
  next: any;
  constructor(data: any) {
    this.element = data;
    this.next = null;
  }
}

class LinkedList {
  head: any;
  length: number;
  constructor() {
    this.head = null;
    this.length = 0;
  }
  // 1. append(element) 向列表尾部添加一个新的项
  append(element: any) {
    const newNode = new Node(element);
    if (!this.head) {
      // 头没有值
      this.head = newNode;
    } else {
      let current = this.head;
      while (current.next) {
        current = current.next;
      }
      current.next = newNode;
    }
    this.length++;
    return true;
  }
  // 2. insetr(position, element) 向列表的特定位置插入一个新的项
  insetr(position: number, element: any) {
    // 2.1 是否越界
    if (position < 0 || position > this.length) return false;
    // 2.2 创建新节点
    const newNode = new Node(element);
    // 2.3 插入元素
    if (position === 0) {
      newNode.next = this.head;
      this.head = newNode;
    } else {
      let index = 0;
      let current = this.head;
      let previous: any = null;
      while (index++ < position) {
        previous = current; // 前一个node
        current = current.next; // 当前node
      }
      previous.next = newNode;
      newNode.next = current;
    }
    this.length++;
    return true;
  }
  // 3. get(position) 获取对应位置的元素
  get(position: number) {
    if (position < 0 || position > this.length - 1) return null;
    let index = 0;
    let current = this.head;
    while (index++ < position) {
      current = current.next;
    }
    return current;
  }
  // 4. indexOf(element) 返回元素在列表中的索引.如果列表中没有该元素则返回-1
  indexOf(element: any) {
    // 获取第一个
    let current = this.head;
    let index = 0;
    // 开始循环
    while (current) {
      if (current.element === element) {
        return index;
      }
      index++;
      current = current.next;
    }
    return -1;
  }
  // 5. removeAt(position) 从列表特定的位置移除一项
  removeAt(position: number) {
    if (position < 0 || position > this.length - 1) return null;
    let current = this.head;
    let previous: any = null;
    let index = 0;
    if (position === 0) {
      this.head = current.next;
    } else {
      while (index++ < position) {
        previous = current;
        current = current.next;
      }
      previous.next = current.next;
    }
    this.length--;
    return current.element;
  }
  // 6. update(position, element) 修改某个位置的元素
  update(position: number, element: any) {
    const result = this.removeAt(position);
    this.insetr(position, element);
    return result;
    // if (position < 0 || position > this.length - 1) return null;
    // let current = this.head;
    // let index = 0;
    // while (index++ < position) {
    //   current = current.next;
    // }
    // current.element = element;
    // return true;
  }

  // 7. remove(element) 从列表中移除一项
  remove(element: any) {
    const index = this.indexOf(element);
    if (index === -1) return;
    return this.removeAt(index);
  }
  // 8. isEmpty() 如果列表中不包含任何元素,返回true,链表的长度大于0则返回false
  isEmpty() {
    return this.length === 0 ? true : false;
  }
  // 9. size() 返回列表包含元素的个数, 与数组的length类似
  size() {
    return this.length;
  }
}

export { LinkedList, Node };

示例


import { LinkedList } from "./linked_list";

const linked = new LinkedList();
console.log(linked, "我是index");

linked.append("aaaaa");
linked.append("bbbb");
linked.append("acccc");
linked.append("cccc");
linked.append("aascsaa");
console.log(linked, "我是index");
linked.insetr(0, "213213123aascsaa");
linked.insetr(1, "woshi id sna wei");
console.log(linked, "我是index");
console.log(linked.get(0), "000");
console.log(linked.get(1), "11111");
console.log(linked.get(2), "22");
console.log(linked.get(3), "33");
console.log(linked, "我是index");
console.log(linked.indexOf("213213123aascsaa"));
console.log(linked.indexOf("cccc"));
console.log(linked.indexOf("ccc1c"));
linked.removeAt(0);
linked.removeAt(1);
console.log(linked, "我是iremoveAtndex");

console.log("------------");
console.log(linked.get(2), "33------");

console.log(linked.update(9, "acac"));

console.log(linked.update(2, "acac"));
console.log(linked.get(2), "33");
console.log(linked, "我是 update");

console.log(linked.remove("woshi id sna wei"));
console.log(linked, "我是 woshi id sna wei");