返回

{ color: red; } #keyword{ background-color: yellow; } #description{ background-color: pink; } </style> </head> <body> 数据结构与算法学习系列之 栈:后进先出,高效率存取!

前端

本文是“数据结构与算法学习系列”的第一篇,我们将介绍栈这一重要的数据结构。栈是一种遵从后进先出(LIFO)原则的有序集合,具有独特的高效存取特性。让我们深入探讨栈的定义、实现、应用和常见面试题,为算法学习打下坚实基础!

目录

  1. 栈的定义
  • 栈的概念及其基本原理。
  1. 栈的实现
  • 基于数组的栈的实现方法。
  • 基于链表的栈的实现方法。
  1. 栈的应用
  • 浏览器历史记录管理。
  • 函数调用中的栈的使用。
  • 操作系统中栈的使用。
  1. 栈的常见面试题
  • 栈的应用场景。
  • 栈的优缺点。
  • 如何判断栈是否为空。

1. 栈的定义

栈是一种遵循后进先出(LIFO)原则的有序集合。LIFO意味着“最后进来的元素,首先出来”,即新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。这种特性使得栈在许多应用场景中都非常有用。

2. 栈的实现

栈可以通过多种方式实现,但最常见的是基于数组和基于链表的实现方法。

基于数组的栈

我们可以使用一个数组来存储栈中的元素,并将数组的末尾视为栈顶。当添加新元素时,我们将该元素添加到数组的末尾;当删除元素时,我们将数组末尾的元素删除。这种实现方式简单易懂,但空间利用率相对较低,因为数组的大小是固定的,而栈可能并不能完全填满数组。

class Stack {
  constructor() {
    this.items = [];
  }

  push(item) {
    this.items.push(item);
  }

  pop() {
    return this.items.pop();
  }

  peek() {
    return this.items[this.items.length - 1];
  }

  isEmpty() {
    return this.items.length === 0;
  }

  size() {
    return this.items.length;
  }
}

基于链表的栈

基于链表的栈可以通过创建一个链表,并将链表的尾部视为栈顶来实现。当添加新元素时,我们将该元素添加到链表的尾部;当删除元素时,我们将链表尾部的元素删除。这种实现方式可以充分利用空间,因为链表的大小是动态的,但链表的插入和删除操作相对复杂。

class Stack {
  constructor() {
    this.head = null;
  }

  push(item) {
    const newNode = {
      data: item,
      next: null,
    };

    if (this.head === null) {
      this.head = newNode;
    } else {
      newNode.next = this.head;
      this.head = newNode;
    }
  }

  pop() {
    if (this.head === null) {
      return null;
    }

    const poppedItem = this.head.data;
    this.head = this.head.next;

    return poppedItem;
  }

  peek() {
    if (this.head === null) {
      return null;
    }

    return this.head.data;
  }

  isEmpty() {
    return this.head === null;
  }

  size() {
    let count = 0;
    let current = this.head;

    while (current !== null) {
      count++;
      current = current.next;
    }

    return count;
  }
}

3. 栈的应用

栈在计算机科学中有着广泛的应用,包括:

  • 浏览器历史记录管理 :浏览器使用栈来管理用户的浏览历史。当用户点击一个链接时,该链接的URL会被压入栈中。当用户点击后退按钮时,栈顶的URL会被弹出,并加载对应的网页。
  • 函数调用中的栈的使用 :当一个函数被调用时,该函数的局部变量和参数会被压入栈中。当函数执行完毕时,这些变量和参数会被弹出栈。这种机制可以保证函数的局部变量和参数在函数执行期间是私有的,不会被其他函数访问。
  • 操作系统中栈的使用 :操作系统使用栈来管理进程的执行。当一个进程被创建时,该进程的代码和数据会被压入栈中。当进程执行完毕时,这些代码和数据会被弹出栈。这种机制可以保证每个进程在执行期间是独立的,不会被其他进程干扰。

4. 栈的常见面试题

栈是算法面试中经常被问到的数据结构。常见的面试题包括:

  • 栈的应用场景 :栈可以用于哪些应用场景?
  • 栈的优缺点 :栈有哪些优点和缺点?
  • 如何判断栈是否为空 :如何判断一个栈是否为空?

掌握这些面试题的答案,可以帮助你轻松应对算法面试中的栈相关问题。

结论

栈是一种非常重要的数据结构,在计算机科学中有着广泛的应用。通过本文的学习,你已经对栈的定义、实现、应用和常见面试题有了一个全面的了解。希望你能在实际项目中灵活应用栈这一数据结构,为你的编程技能锦上添花!