목차
2.2 스택 구현
2.3 스택의 응용
3.2 队列的实现
3.3 队列的应用
웹 프론트엔드 JS 튜토리얼 JavaScript의 스택 및 큐에 대한 알고리즘 분석

JavaScript의 스택 및 큐에 대한 알고리즘 분석

Jan 16, 2019 am 09:36 AM
javascript 프런트 엔드 데이터 구조

이 기사의 내용은 JavaScript의 스택 및 큐 알고리즘 분석에 관한 것입니다. 이는 특정 참고 가치가 있으므로 도움이 될 수 있습니다.

1. 데이터 구조를 이해하세요

데이터 구조란 무엇인가요? Wikipedia의 설명은 다음과 같습니다

데이터 구조는 컴퓨터가 데이터를 저장하고 구성하는 방식입니다.

데이터 구조는 인터페이스 또는 캡슐화를 의미합니다. 데이터 구조는 두 기능 간의 인터페이스로 볼 수도 있고 데이터 유형의 결합으로 구성된 저장소로 볼 수도 있습니다. 콘텐츠 액세스 방법 캡슐화

우리는 일상적인 코딩에서 데이터 구조를 사용합니다. 왜냐하면 배열은 가장 간단한 메모리 데이터 구조이기 때문입니다. 다음은 일반적인 데이터 구조입니다

  • Array(Array)

  • Stack(Stack)

  • Queue

  • Linked List

  • Tree

  • Graph

  • Heap

  • Hash

스택과 큐에 대해 알아봅시다..

2. 스택

2.1 스택 데이터 구조

스택은 LIFO(후입선출) 원칙을 따르는 정렬된 컬렉션입니다. 새로 추가되거나 삭제될 요소는 스택의 동일한 끝(스택 상단이라고 함)에 저장되고 다른 쪽 끝은 스택의 하단이라고 합니다. 스택에서 새 요소는 스택 상단 근처에 있고 이전 요소는 하단 근처에 있습니다.

JavaScript의 스택 및 큐에 대한 알고리즘 분석

인생의 사물에 비유: 책이나 접시를 함께 밀어 넣은 더미

2.2 스택 구현

일반적인 스택은 일반적으로 다음 방법을 사용합니다.

푸시를 눌러 하나(또는 여러 개)를 추가합니다. 스택의 상단

pop은 스택의 상단 요소를 오버플로하고 동시에 제거된 요소를 반환합니다.

peek는 스택을 수정하지 않고 스택의 상단 요소를 반환합니다.

isEmpty는 스택에 요소가 없으면 true를 반환합니다. stack, 그렇지 않으면 false를 반환

size return 스택의 요소 수

clear 스택 지우기

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;
  }
  // 栈元素个数
  size() {
    return this._items.length;
  }
  // 清空栈
  clear() {
    this._items = [];
  }
}
로그인 후 복사

이제 데이터 구조에서 스택이 무엇인지 되돌아보고 생각해 봅시다.

갑자기 나는 그것이 그다지 마법적인 것이 아니라 단지 원본 데이터를 캡슐화한 것에 불과하다는 것을 발견했습니다. 캡슐화의 결과는 다음과 같습니다. 내부 요소는 신경 쓰지 않고 스택의 최상위 요소만 작동합니다. 이 경우 코딩을 더 쉽게 제어할 수 있습니다.

2.3 스택의 응용

(1) 십진수를 임의의 진수로 변환

요구 사항: 함수가 주어졌을 때 목표 값과 진수를 입력하고 해당하는 진수(최대 16진수)를 출력합니다.

baseConverter(10, 2) ==> 1010
baseConverter(30, 16) ==> 1E
로그인 후 복사

분석 : 진수변환의 본질은 목표값을 기준값으로 한 번에 나누어서 반올림한 값이 새로운 목표값이 되고, 목표값이 0보다 작아질 때까지 나머지를 기록하고 마지막으로 나머지를 역순으로 합치는 것입니다. , 캔입니다. 스택을 사용하여 나머지를 기록하고 스택에 밀어넣고 결합할 때 튀어나옵니다

// 进制转换
function baseConverter(delNumber, base) {
  const stack = new Stack();
  let rem = null;
  let ret = [];
  // 十六进制中需要依次对应A~F
  const digits = '0123456789ABCDEF';

  while (delNumber > 0) {
    rem = Math.floor(delNumber % base);
    stack.push(rem);
    delNumber = Math.floor(delNumber / base);
  }

  while (!stack.isEmpty()) {
    ret.push(digits[stack.pop()]);
  }

  return ret.join('');
}

console.log(baseConverter(100345, 2)); //输出11000011111111001
console.log(baseConverter(100345, 8)); //输出303771
console.log(baseConverter(100345, 16)); //输出187F9
로그인 후 복사

(2) 역 폴란드식 계산

요구 사항: 역 폴란드 식, 접미사 식이라고도 하며 복잡한 형식으로 변환합니다. 표현식을 간단한 연산에 의존하여 계산 결과를 얻는 표현식으로, 예를 들어 (a+b)*(c+d)a b + c d + *(a+b)*(c+d)转换为a b + c d + *

["4", "13", "5", "/", "+"] ==> (4 + (13 / 5)) = 6
["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
==> ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
로그인 후 복사

分析: 以符号为触发节点,一旦遇到符号,就将符号前两个元素按照该符号运算,并将新的结果入栈,直到栈内仅一个元素

function isOperator(str) {
  return ['+', '-', '*', '/'].includes(str);
}
// 逆波兰表达式计算
function clacExp(exp) {
  const stack = new Stack();
  for (let i = 0; i <p><strong>(3)利用普通栈实现一个有<code>min</code>方法的栈</strong></p><p><strong>思路:</strong> 使用两个栈来存储数据,其中一个命名为<code>dataStack</code>,专门用来存储数据,另一个命名为<code>minStack</code>,专门用来存储栈里最小的数据。始终保持两个栈中的元素个数相同,压栈时判别压入的元素与<code>minStack</code>栈顶元素比较大小,如果比栈顶元素小,则直接入栈,否则复制栈顶元素入栈;弹出栈顶时,两者均弹出即可。这样<code>minStack</code>的栈顶元素始终为最小值。</p><pre class="brush:php;toolbar:false">class MinStack {
  constructor() {
    this._dataStack = new Stack();
    this._minStack = new Stack();
  }

  push(item) {
    this._dataStack.push(item);
    // 为空或入栈元素小于栈顶元素,直接压入该元素
    if (this._minStack.isEmpty() || this._minStack.peek() > item) {
      this._minStack.push(item);
    } else {
      this._minStack.push(this._minStack.peek());
    }
  }

  pop() {
    this._dataStack.pop();
    return this._minStack.pop();
  }

  min() {
    return this._minStack.peek();
  }
}

const minstack = new MinStack();

minstack.push(3);
minstack.push(4);
minstack.push(8);
console.log(minstack.min()); // 3
minstack.push(2);
console.log(minstack.min()); // 2
로그인 후 복사

三、队列

3.1 队列数据结构

队列是遵循先进先出(FIFO,也称为先来先服务)原则的一组有序的项。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾

JavaScript의 스택 및 큐에 대한 알고리즘 분석

类比:日常生活中的购物排队

3.2 队列的实现

普通的队列常用的有以下几个方法:

  • enqueue 向队列尾部添加一个(或多个)新的项

  • dequeue 移除队列的第一(即排在队列最前面的)项,并返回被移除的元素

  • head 返回队列第一个元素,队列不做任何变动

  • tail

    class Queue {
      constructor() {
        this._items = [];
      }
    
      enqueue(item) {
        this._items.push(item);
      }
    
      dequeue() {
        return this._items.shift();
      }
    
      head() {
        return this._items[0];
      }
    
      tail() {
        return this._items[this._items.length - 1];
      }
    
      isEmpty() {
        return !this._items.length;
      }
    
      size() {
        return this._items.length;
      }
    
      clear() {
        this._items = [];
      }
    }
    로그인 후 복사
    로그인 후 복사
    로 변환됩니다. 🎜분석: 🎜 기호를 트리거 노드로 사용합니다. 기호가 발견되면 기호의 처음 두 요소가 기호에 따라 작동되고 스택에 요소가 하나만 있을 때까지 새 결과가 스택에 푸시됩니다. 🎜
    // 创建一个长度为100的数组
    const arr_100 = Array.from({ length: 100 }, (_, i) => i*i);
    
    function delRing(list) {
      const queue = new Queue();
      list.forEach(e => { queue.enqueue(e); });
      
      let index = 0;
      while (queue.size() !== 1) {
        const item = queue.dequeue();
        index += 1;
        if (index % 3 !== 0) {
          queue.enqueue(item);
        }
      }
    
      return queue.tail();
    }
    
    console.log(delRing(arr_100)); // 8100 此时index=297
    로그인 후 복사
    로그인 후 복사
    🎜🎜 (3) 일반 스택을 사용하여 min 메서드로 스택 구현 🎜🎜🎜🎜 아이디어: 🎜 두 개의 스택을 사용하여 데이터를 저장하고 그 중 하나의 이름은 dataStack code>는 데이터를 저장하는 데 특별히 사용되며 다른 하나는 <code>minStack이라는 이름으로 스택에서 가장 작은 데이터를 저장하는 데 특별히 사용됩니다. 두 스택의 요소 수를 항상 동일하게 유지하세요. 스택을 푸시할 때 푸시된 요소의 크기를 minStack 스택의 맨 위에 있는 요소와 비교하세요. 스택의 맨 위에서 스택으로 직접 푸시하고, 그렇지 않으면 스택을 복사합니다. 맨 위 요소가 스택에서 팝되면 두 요소가 모두 팝될 수 있습니다. 이런 방식으로 minStack의 최상위 요소는 항상 최소값입니다. 🎜
    function fibonacci(n) {
        const queue = new Queue();
        queue.enqueue(1);
        queue.enqueue(1);
        
        let index = 0;
        while(index 🎜🎜3. 대기열🎜🎜🎜🎜3.1 대기열 데이터 구조🎜🎜 대기열은 선입선출(FIFO, 선착순이라고도 함) 원칙을 따르는 정렬된 항목 집합입니다. . 큐는 꼬리에 새 요소를 추가하고 맨 위에서 요소를 제거합니다. 가장 최근에 추가된 요소는 대기열 끝에 있어야 합니다 🎜🎜<img src="/static/imghw/default1.png" data-src="https://img.php.cn//upload/image/578/667/838/1547602503534750.png" class="lazy" title="1547602503534750.png " alt="JavaScript의 스택 및 큐에 대한 알고리즘 분석">🎜🎜🎜비유: 일상생활의 쇼핑 대기열🎜🎜3.2 대기열 구현🎜🎜공통 대기열은 일반적으로 다음 방법을 사용합니다.🎜🎜🎜🎜<code>enqueue code> 추가 대기열 끝에 하나 이상의 새 항목 🎜🎜🎜🎜<code>dequeue</code> 대기열의 첫 번째 항목(즉, 대기열의 맨 앞부분)을 제거하고 제거된 항목 요소를 반환합니다 🎜🎜 🎜🎜<code>head</code> 대기열을 변경하지 않고 대기열의 첫 번째 요소를 반환합니다.🎜🎜🎜🎜<code>tail</code> 대기열을 변경하지 않고 대기열의 마지막 요소를 반환합니다. 🎜</code>
    로그인 후 복사
  • isEmpty 队列内无元素返回true,否则返回false

  • size 返回队列内元素个数

  • clear 清空队列

class Queue {
  constructor() {
    this._items = [];
  }

  enqueue(item) {
    this._items.push(item);
  }

  dequeue() {
    return this._items.shift();
  }

  head() {
    return this._items[0];
  }

  tail() {
    return this._items[this._items.length - 1];
  }

  isEmpty() {
    return !this._items.length;
  }

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

  clear() {
    this._items = [];
  }
}
로그인 후 복사
로그인 후 복사

与栈类比,栈仅能操作其头部,队列则首尾均能操作,但仅能在头部出尾部进。当然,也印证了上面的话:栈和队列并不关心其内部元素细节,也无法直接操作非首尾元素。

3.3 队列的应用

(1)约瑟夫环(普通模式)

要求: 有一个数组a[100]存放0~99;要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数。

分析: 按数组创建队列,依次判断元素是否满足为指定位置的数,如果不是则enqueue到尾部,否则忽略,当仅有一个元素时便输出

// 创建一个长度为100的数组
const arr_100 = Array.from({ length: 100 }, (_, i) => i*i);

function delRing(list) {
  const queue = new Queue();
  list.forEach(e => { queue.enqueue(e); });
  
  let index = 0;
  while (queue.size() !== 1) {
    const item = queue.dequeue();
    index += 1;
    if (index % 3 !== 0) {
      queue.enqueue(item);
    }
  }

  return queue.tail();
}

console.log(delRing(arr_100)); // 8100 此时index=297
로그인 후 복사
로그인 후 복사

(2)菲波那切数列(普通模式)

要求: 使用队列计算斐波那契数列的第n项
分析: 斐波那契数列的前两项固定为1,后面的项为前两项之和,依次向后,这便是斐波那契数列。

function fibonacci(n) {
    const queue = new Queue();
    queue.enqueue(1);
    queue.enqueue(1);
    
    let index = 0;
    while(index <p><strong>(3)用队列实现一个栈</strong></p><p><strong>要求:</strong> 用两个队列实现一个栈<br><strong>分析:</strong> 使用队列实现栈最主要的是在队列中找到栈顶元素并对其操作。具体的思路如下:</p><ol class=" list-paddingleft-2">
<li><p>两个队列,一个备份队列<code>emptyQueue</code>,一个是数据队列<code>dataQueue</code>;</p></li>
<li><p>在确认栈顶时,依次<code>dequeue</code>至备份队列,置换备份队列和数据队列的引用即可</p></li>
</ol><pre class="brush:php;toolbar:false">class QueueStack {
  constructor() {
    this.queue_1 = new Queue();
    this.queue_2 = new Queue();
    this._dataQueue = null; // 放数据的队列
    this._emptyQueue = null; // 空队列,备份使用
  }

  // 确认哪个队列放数据,哪个队列做备份空队列
  _initQueue() {
    if (this.queue_1.isEmpty() && this.queue_2.isEmpty()) {
      this._dataQueue = this.queue_1;
      this._emptyQueue = this.queue_2;
    } else if (this.queue_1.isEmpty()) {
      this._dataQueue = this.queue_2;
      this._emptyQueue = this.queue_1;
    } else {
      this._dataQueue = this.queue_1;
      this._emptyQueue = this.queue_2;
    }
  };

  push(item) {
    this.init_queue();
    this._dataQueue.enqueue(item);
  };

  peek() {
    this.init_queue();
    return this._dataQueue.tail();
  }

  pop() {
    this.init_queue();
    while (this._dataQueue.size() > 1) {
      this._emptyQueue.enqueue(this._dataQueue.dequeue());
    }
    return this._dataQueue.dequeue();
  };
};
로그인 후 복사

学习了栈和队列这类简单的数据结构,我们会发现。数据结构并没有之前想象中那么神秘,它们只是规定了这类数据结构的操作方式:栈只能对栈顶进行操作,队列只能在尾部添加在头部弹出;且它们不关心内部的元素状态。

위 내용은 JavaScript의 스택 및 큐에 대한 알고리즘 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP와 Vue: 프런트엔드 개발 도구의 완벽한 조합 PHP와 Vue: 프런트엔드 개발 도구의 완벽한 조합 Mar 16, 2024 pm 12:09 PM

PHP와 Vue: 프론트엔드 개발 도구의 완벽한 조합 오늘날 인터넷이 빠르게 발전하는 시대에 프론트엔드 개발은 점점 더 중요해지고 있습니다. 사용자가 웹 사이트 및 애플리케이션 경험에 대한 요구 사항이 점점 더 높아짐에 따라 프런트 엔드 개발자는 보다 효율적이고 유연한 도구를 사용하여 반응형 및 대화형 인터페이스를 만들어야 합니다. 프론트엔드 개발 분야의 두 가지 중요한 기술인 PHP와 Vue.js는 함께 사용하면 완벽한 도구라고 볼 수 있습니다. 이 기사에서는 독자가 이 두 가지를 더 잘 이해하고 적용할 수 있도록 PHP와 Vue의 조합과 자세한 코드 예제를 살펴보겠습니다.

Java 함수 비교를 사용하여 복잡한 데이터 구조 비교 Java 함수 비교를 사용하여 복잡한 데이터 구조 비교 Apr 19, 2024 pm 10:24 PM

Java에서 복잡한 데이터 구조를 사용할 때 Comparator는 유연한 비교 메커니즘을 제공하는 데 사용됩니다. 구체적인 단계에는 비교기 클래스 정의, 비교 논리를 정의하기 위한 비교 메서드 재작성 등이 포함됩니다. 비교기 인스턴스를 만듭니다. Collections.sort 메서드를 사용하여 컬렉션 및 비교기 인스턴스를 전달합니다.

프론트엔드 면접관이 자주 묻는 질문 프론트엔드 면접관이 자주 묻는 질문 Mar 19, 2024 pm 02:24 PM

프론트엔드 개발 인터뷰에서 일반적인 질문은 HTML/CSS 기초, JavaScript 기초, 프레임워크 및 라이브러리, 프로젝트 경험, 알고리즘 및 데이터 구조, 성능 최적화, 크로스 도메인 요청, 프론트엔드 엔지니어링, 디자인 패턴, 새로운 기술 및 트렌드. 면접관 질문은 후보자의 기술적 능력, 프로젝트 경험, 업계 동향에 대한 이해를 평가하기 위해 고안되었습니다. 따라서 지원자는 자신의 능력과 전문성을 입증할 수 있도록 해당 분야에 대한 충분한 준비를 갖추어야 합니다.

프런트엔드 모듈형 ESM이란 무엇입니까? 프런트엔드 모듈형 ESM이란 무엇입니까? Feb 25, 2024 am 11:48 AM

프론트엔드 ESM이란 무엇입니까? 프론트엔드 개발에서 ESM은 ECMAScript 사양을 기반으로 한 모듈식 개발 방법인 ECMAScriptModules를 참조합니다. ESM은 더 나은 코드 구성, 모듈 간 격리, 재사용성과 같은 많은 이점을 제공합니다. 이 기사에서는 ESM의 기본 개념과 사용법을 소개하고 몇 가지 구체적인 코드 예제를 제공합니다. ESM의 기본 개념 ESM에서는 코드를 여러 모듈로 나눌 수 있으며 각 모듈은 다른 모듈에 대한 일부 인터페이스를 노출합니다.

Java 데이터 구조 및 알고리즘: 심층 설명 Java 데이터 구조 및 알고리즘: 심층 설명 May 08, 2024 pm 10:12 PM

데이터 구조와 알고리즘은 Java 개발의 기초입니다. 이 기사에서는 Java의 주요 데이터 구조(예: 배열, 연결 목록, 트리 등)와 알고리즘(예: 정렬, 검색, 그래프 알고리즘 등)을 자세히 살펴봅니다. 이러한 구조는 배열을 사용하여 점수를 저장하고, 연결된 목록을 사용하여 쇼핑 목록을 관리하고, 스택을 사용하여 재귀를 구현하고, 대기열을 사용하여 스레드를 동기화하고, 트리 및 해시 테이블을 사용하여 빠른 검색 및 인증을 저장하는 등 실제 사례를 통해 설명됩니다. 이러한 개념을 이해하면 효율적이고 유지 관리가 가능한 Java 코드를 작성할 수 있습니다.

Go 언어 프런트엔드 기술 탐색: 프런트엔드 개발을 위한 새로운 비전 Go 언어 프런트엔드 기술 탐색: 프런트엔드 개발을 위한 새로운 비전 Mar 28, 2024 pm 01:06 PM

빠르고 효율적인 프로그래밍 언어인 Go 언어는 백엔드 개발 분야에서 널리 사용됩니다. 그러나 Go 언어를 프런트엔드 개발과 연관시키는 사람은 거의 없습니다. 실제로 프런트엔드 개발에 Go 언어를 사용하면 효율성이 향상될 뿐만 아니라 개발자에게 새로운 지평을 열어줄 수도 있습니다. 이 기사에서는 프런트엔드 개발에 Go 언어를 사용할 수 있는 가능성을 살펴보고 독자가 이 영역을 더 잘 이해할 수 있도록 구체적인 코드 예제를 제공합니다. 전통적인 프런트엔드 개발에서는 사용자 인터페이스를 구축하기 위해 JavaScript, HTML, CSS를 사용하는 경우가 많습니다.

Golang과 프런트엔드 기술의 결합: Golang이 프런트엔드 분야에서 어떤 역할을 하는지 살펴보세요. Golang과 프런트엔드 기술의 결합: Golang이 프런트엔드 분야에서 어떤 역할을 하는지 살펴보세요. Mar 19, 2024 pm 06:15 PM

Golang과 프런트엔드 기술의 결합: Golang이 프런트엔드 분야에서 어떤 역할을 하는지 살펴보려면 구체적인 코드 예제가 필요합니다. 인터넷과 모바일 애플리케이션의 급속한 발전으로 인해 프런트엔드 기술이 점점 더 중요해지고 있습니다. 이 분야에서는 강력한 백엔드 프로그래밍 언어인 Golang도 중요한 역할을 할 수 있습니다. 이 기사에서는 Golang이 프런트엔드 기술과 어떻게 결합되는지 살펴보고 특정 코드 예제를 통해 프런트엔드 분야에서의 잠재력을 보여줍니다. 프론트엔드 분야에서 Golang의 역할은 효율적이고 간결하며 배우기 쉬운 것입니다.

PHP 백엔드에서 프런트엔드 개발로의 전환 경로 PHP 백엔드에서 프런트엔드 개발로의 전환 경로 Mar 12, 2024 pm 06:45 PM

PHP 백엔드에서 프론트엔드 개발로의 전환 인터넷 기술의 지속적인 발전과 함께 전체 소프트웨어 개발 분야에서 프론트엔드 개발의 중요성이 더욱 부각되고 있습니다. PHP 백엔드 개발에 종사하는 많은 엔지니어들은 프론트엔드 개발 학습의 중요성을 깨닫기 시작했고, 이에 따라 기술의 방향을 바꾸기 시작했습니다. 이 기사에서는 PHP 백엔드 개발 엔지니어가 어떻게 프런트엔드 개발 분야로 원활하게 전환할 수 있는지 프로세스를 살펴보고 구체적인 코드 예제를 제공합니다. 1. 프론트엔드 개발의 기본지식을 이해한다 HTML/CSS 기초 프론트엔드 개발의 기본은 HTML과

See all articles