使用js实现常见的数据结构---链表,队列,栈,树

:本文只作为数据结构的实现参考和个人理解

链表

链表是由多个节点(node)连接起来的,每个节点包含了一些存储的数据和指向下一个节点的指针,

  1. 链表:多个连续的节点构成,
  2. 节点:包含一串数据,以及下一个节点的数据

注意:链表是由顺序的数据集结构,访问链表只能从头到尾的访问

 

// 定义一个节点
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

// 定义一个链表
class LinkedList {
  constructor() {
    this.first = null;//初始化头节点
  }
  // 添加节点
  addNode(data) {
    const node = new Node(data);
    if (this.first === null) {
      this.first = node;
    } else {
      let current = this.first;
      while (current.next) {//后续节点存在
        current = current.next;//移动到下一个节点
      }
      current.next = node;
    }
  }
  // 删除节点
  removeNode(data) {
    if (this.first === null) {
      return;
    }
    if (this.first.data === data) {
      this.first = this.first.next;
      return;
    }
    let current = this.first;
    while (current.next) {
      if (current.next.data === data) {
        current.next = current.next.next;
        return;
      }
      current = current.next;
    }
  }
  // 遍历链表
  getList() {
    let current = this.first;
    let arr = []
    while (current) {
      arr.push(current.data);
      current = current.next;
    }
    return arr.reduce((a, b) => a + '->' + b, '');
  }
}

const list = new LinkedList();
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(4);
list.addNode(5);
console.log(list.getList());
list.removeNode(3);
console.log(list.getList());
console.log(list);
console.log(list.first.next);

队列

先进先出的数据结构:每次只能从队列的尾部添加数据,从队列的头部访问数据,

  1. 一头放数据,一头拿数据,不可直接访问中间的数据
// 创建一个队列
class Queue {
  #value
  constructor(){
    this.#value = []
  }
  get value(){
    return this.#value[this.#value.length - 1];//返回最后一个元素
  }
  set value(val){
    this.#value.splice(0, 0, val);//头部添加元素
  }
  delValue(){
    this.#value.pop()//删除最后一个元素
  }
  getQueue(){
    return this.#value.toReversed().reduce((a,b)=> a+'->'+b, '')
  }
}

// 先进先出
const queue = new Queue()
queue.value = 1
queue.value = 2
queue.value = 3
queue.value = 4
queue.value = 5
queue.value = 6
queue.value = 7
console.log(queue.getQueue())
console.log(queue.value) 
queue.delValue()
queue.delValue()
console.log(queue.value) 

 栈

后进先出的数据结构:只有一个出入口,数据的增减都在尾部

  1. 只能在链式数据的一端进行访问数据和修改数据
// 后进先出
class Stack {
  #value
  constructor() {
    this.#value = []
  }
  get value() {
    return this.#value[this.#value.length - 1]
  }
  set value(val) {
    this.#value.push(val)
  }

}

const stack = new Stack()
stack.value = 1
stack.value = 2
stack.value = 3
console.log(stack.value)

 

树是一个二维结构,一颗树从根节点出发,连接着多个子节点,每个子节点又连接着子孙节点,循环往复就组成了一棵树;

注意:在树中子节点只能指向子孙节点不能指向父节点,根节点只有一个,他是所有节点的父节点,不能被任何节点指向

  1. 根节点:每个数的根节点只能有一个(最顶层的节点)
  2. 叶节点:没有子节点的节点(最底层的节点)

 

class TreeNode {
  constructor(data) {
    this.data = data;
    this.children = null;
  }
  add(data) {// 向节点添加子节点
    if (this.children === null) {// 如果无字节点添加节点之前,设置属性为空数组
      this.children = [];
    }
    this.children.push(new TreeNode(data));
  }
  remove(data) {// 移除节点的子节点
    if (this.children === null) {
      return false;
    }
    for (let i = 0; i < this.children.length; i++) {
      if (this.children[i].data === data) {
        this.children.splice(i, 1);
        return true;
      }
    }
    return false;
  }
  // 层序遍历树
  // 记录层数, 每层节点放入一个数组
  log() {
    const result = []; // 存放结果的容器
    let level = 0; // 记录层数,默认为顶层
    result[level] = [String(level), this.data]; // 将根节点放入第一层,string表示层级
    level++;// 下一层

    function loop(node, level) {
      if (!node.children) {// 没有子节点退出递归
        return;
      }
      if (!result[level]) {// 如果没有创建数组,则创建
        result[level] = [String(level)];
      }

      node.children.map(item => {
        result[level].push(item.data);// 将结果放置再本层
        loop(item, level + 1);// 递归调用下一层

      })

    }
    loop(this, level);
    console.log(result);
  }
}

const tree = new TreeNode(1);
tree.add(2);
tree.add(3);
tree.children[0].add(4);
tree.children[0].add(5);
tree.children[1].add(6);
tree.children[1].add(7);
tree.children[0].children[0].add(8);
tree.log();

console.log(tree)

总结 

        通过js的class的功能,可以很清晰的实现这些数据结构,本质上看数据结构表示的是按照一定的关系顺序存放数据,每个数据的单位都是节点,节点包含了一个单位数据(任意大小)和下一个节点的地址(引用),这里是使用js对象属性的方式来实现的;

        一维的数据结构中,链表是最基本的数据结构,它按顺序连接了多个节点,通过头节点就可以获取到整个链表数据,其他的数据结构(队列,栈)都类似链表结构的变式

        树是二维的数据结构,它的关系是一对多,一个节点指向了多个节点,同时树是开放的,一颗树是没有环状结构的(子节点不会引用父节点),一旦出现环状结构,就变成了图(封闭的二维数据结构)

这些基本结构的映射关系: 点(节点)--- 线(一维结构) --- 面 (二维结构)

补充:

        和数组的关系:数组也是一种数据结构,但它是连续的空间(连续的变量集合),而链表这样的结构它的数据是分散的(各处的变量集合)

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 15:16:03       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 15:16:03       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 15:16:03       45 阅读
  4. Python语言-面向对象

    2024-07-20 15:16:03       55 阅读

热门阅读

  1. Springboo3中使用虚线程

    2024-07-20 15:16:03       17 阅读
  2. C#面:MVC中的TempData\ViewBag\ViewData区别?

    2024-07-20 15:16:03       18 阅读
  3. Linux下载网络文档

    2024-07-20 15:16:03       15 阅读
  4. 网络爬虫基础介绍

    2024-07-20 15:16:03       16 阅读
  5. Linux内存从0到1学习笔记(8.20 ION (二))

    2024-07-20 15:16:03       14 阅读
  6. 基于 Go1.19 的站点模板爬虫:构建与实战

    2024-07-20 15:16:03       19 阅读
  7. Redis

    Redis

    2024-07-20 15:16:03      15 阅读
  8. 订单管理系统需求规范

    2024-07-20 15:16:03       21 阅读
  9. E15.【C语言】练习:逗号表达式和前置后置++

    2024-07-20 15:16:03       17 阅读