算法与数据结构: 数据结构

70 阅读2分钟

队列 Queue

  • [先进先出FIFO]的数组

image.png

代码:

index.html

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>队列示例</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div id="screen"></div>
    <div class="actions">
      <button id="createNumber">取号</button>
      <button id="callNumber">叫号</button>
    </div>
    <div>当前号码 <span id="newNumber"></span></div>
    <div>当前队列 <span id="queue"></span></div>
    <script src="./main.js"></script>
  </body>
</html>

main.js

const divScreen = document.querySelector("#screen");
const btnCreateNumber = document.querySelector("#createNumber");
const btnCallNumber = document.querySelector("#callNumber");
const spanNewNumber = document.querySelector("#newNumber");
const spanQueue = document.querySelector("#queue");

let n = 0;
let queue = [];

btnCreateNumber.onclick = () => {
  n += 1;
  //queue.push(n);
  queue.push.call(queue, n);
  spanNewNumber.innerText = n;
  spanQueue.innerText = JSON.stringify(queue);
};

btnCallNumber.onclick = () => {
  if (queue.length === 0) {
    return;
  }
  //const m = queue.shift();
  const m = queue.shift.call(queue);
  divScreen.innerText = `请 ${m} 号就餐`;
  spanQueue.innerText = JSON.stringify(queue);
};

  • 什么是队列的数据结构?

  • 答: 它是一个类似数组的东西,只提供push入队,shift出队两个操作,提供这样的结构和这两个操作,就是对列。

栈 Stack

  • [后进先出LIFO]的数组

image.png

image.png

链表 Linked list

  • 一个链一个

image.png

image.png

const createList = (value) => {
  return createNode(value);
};
const appendList = (list, value) => {
  const node = createNode(value);
  list.next = node;
  return node;
};

const removeFromList = (list, node) => {
  let x = list;
  let p = node; // 课堂里将 p 初始化为 null,这里改为 node
  while (x !== node && x !== null) {
    // 课堂里忘了对 null 进行处理,如果 node 不在 list 中,x 就可能为 null
    p = x;
    x = x.next;
  }
  if (x === null) {
    // 若 x 为 null,则不需要删除,直接 return, false 表示无法删除不在list里的节点
    return false;
  } else if (x === p) {
    // 这说明要删除的节点是第一个节点
    p = x.next;
    return p; // 如果删除的是第一个节点,那么就要把新 list 的头节点 p 返回给外面,即 newList = removeFromList(list, list)
  } else {
    p.next = x.next;
    return list; // 如果删除的不是第一个节点,返回原来的 list 即可
  }
};

// console.log(p === null || x 的上一个节点)
// console.log(x === node || x === null)
//p.next = x.next;
//if (list === node) {
//如果删除的是第一个节点
//list指向第2个节点
//list = node.next;
//} else {
// 如果删除的是第二个节点
// 第1个节点.next = 第2个节点.next
//if (list.next === node) {
//list.next = node.next;
//} else {
// 如果删除的是第三个节点
// 第2个节点.next = 第3个节点.next
//if (list.next.next === node) {
//list.next.next = node.next;
//} else {
// 如果删除的是第4个节点
// 第3个节点.next = 第4个节点.next
//if (list.next.next.next === node) {
//list.next.next.next = node.next;
//}
//}
//}
//}
//};

const createNode = (value) => {
  return {
    data: value,
    next: null,
  };
};

const travelList = (list, fn) => {
  let x = list;
  while (x !== null) {
    fn(x);
    x = x.next;
  }
};
const list = createList(10);
const node = list; 
// node 就是 list 的第一个节点了现在
const newList = removeFromList(list, node);
// 必须用 newList 获取返回值才能拿到删除了第一个节点的新 list
travelList(list, (node) => {
  console.log(node.data);
});

哈希表 key-value pairs

image.png

树 tree

  • 一个链多个

image.png

const createTree = (value) => {
  return {
    data: value,
    children: null,
    parent: null,
  };
};
const addChild = (node, value) => {
  const newNode = {
    data: value,
    children: null,
    parent: null,
  };
  node.children = node.children || [];
  node.children.push(newNode);
  return newNode;
};
const travel = (tree, fn) => {
  fn(tree);
  if (!tree.children) {
    return;
  }
  for (let i = 0; i < tree.children.length; i++) {
    travel(tree.children[i], fn);
  }
};
const find = (tree, node) => {
  if (tree === node) {
    return tree;
  } else if (tree.children) {
    for (let i = 0; i < tree.children.length; i++) {
      const result = find(tree.children[i], node);
      if (result) {
        return result;
      }
    }
    return undefined;
  } else {
    return undefined;
  }
};

const removeNode = (tree, node) => {
  const siblings = node.parent.children;
  let index = 0;
  for (let i = 1; i < siblings.length; i++) {
    if (siblings[i] === node) {
      index = 1;
    }
  }
  siblings.splice(index, 1);
};

const tree = createTree(10);
const node2 = addChild(tree, 20);
addChild(tree, 30);
addChild(tree, 40);
addChild(tree, 50);
addChild(node2, 201);
addChild(node2, 202);
addChild(node2, 203);
addChild(node2, 204);
console.log(tree);

const fn = (node) => {
  console.log(node.data);
};
travel(tree, fn);