목차
전체 버전 코드 GitHub 창고 주소:
Java java지도 시간 Java 순환 큐 소개(코드 예)

Java 순환 큐 소개(코드 예)

Mar 27, 2019 am 10:31 AM
java

이 기사는 Java 순환 대기열(코드 예제)에 대한 소개를 제공합니다. 이는 특정 참조 가치가 있으므로 도움이 될 수 있습니다.

배열 큐로 인해 발생하는 문제를 해결하기 위해 이 문서에서는 순환 큐를 소개합니다.

아이디어 분석 일러스트레이션

죄송합니다. 게시된 사진에 요소를 이동하거나 삭제하는 등의 애니메이션 효과를 적용하는 데는 그다지 능숙하지 않기 때문에(결국 이렇게 보는 것이 모든 사람에게 더 직관적입니다) ), 저자는 여기에서 정적 방법만 사용할 수 있습니다. 그림은 모든 사람이 구현 원리를 이해하는 데 도움이 되도록 사용됩니다. 이를 수행하는 방법을 아는 사람이 있으면 댓글 영역에서 지혜를 공유하십시오.

여기서 용량이 8인 배열을 선언하고 인덱스 0-7을 표시한 다음 fronttail를 사용하여 각각 대기열, 헤드를 나타냅니다. 그리고 tail of the team; 아래 그림에서 fronttail의 위치는 처음에 인덱스 0의 위치를 ​​가리키며, 이는 front = = tai <font color="red"></font> 대기열이 비어 있을 때 다음 소개를 구별하려면 누구나 이 점을 명심해야 합니다. 대기열이 거의 가득 차면 심각한 상황fronttail分别来表示队列的,队首和队尾;在下图中,fronttail的位置一开始都指向是了索引0的位置,这意味着当front == tai的时候 <font color="'red'"></font>队列为空 大家务必牢记这一点,以便区分后面介绍队列快满时的临界条件

Java 순환 큐 소개(코드 예)

为了大家更好地理解下面的内容,在这里,我简单做几点说明

front:表示队列队首,始终指向队列中的第一个元素(当队列空时,front指向索引为0的位置)

tail:表示队列队尾,始终指向队列中的最后一个元素的下一个位置

元素入队,维护tail的位置,进行tail++操作

元素出队,维护front的位置,进行front++操作上面所说的,元素进行入队和出队操作,都简单的进行++操作,来维护tailfront的位置,其实是不严谨的,正确的维护tail的位置应该是(tail + 1) % capacity,同理front的位置应该是(front + 1) % capacity,这也是为什么叫做循环队列的原因,大家先在这里知道下,暂时不理解也没关系,后面相信大家会知晓。

下面我们看一下,现在如果有一个元素a入队,现在的示意图:

Java 순환 큐 소개(코드 예)

我们现在看到了元素a入队,我们的tail指向的位置发生了变化,进行了++操作,而front的位置,没有发生改变,仍旧指向索引为0的位置,还记得笔者上面所说的,front的位置,始终指向队列中的第一个元素,tail的位置,始终指向队列中的最后一个元素的下一个位置

现在,我们再来几个元素b、c、d、e进行入队操作,看一下此时的示意图:

Java 순환 큐 소개(코드 예)

想必大家都能知晓示意图是这样,好像没什么太多的变化(还请大家别着急,笔者这也是方便大家理解到底是什么循环队列,还请大家原谅我O(∩_∩)O哈!)

看完了元素的入队的操作情况,那现在我们看一下,元素的出队操作是什么样的?

元素a

2264010177 - 5c9a32e92128f_articlex.png

Java 순환 큐 소개(코드 예)

다음 내용을 모두가 더 잘 이해할 수 있도록 몇 가지 간단한 설명을 하겠습니다.

front: 대기열의 선두를 나타냅니다. 항상 대기열을 가리키는 첫 번째 요소(큐가 비어 있는 경우 앞쪽은 인덱스 0의 위치를 ​​가리킴)

tail: 대기열의 꼬리를 나타내며 항상 다음 위치를 가리킵니다. 대기열의 마지막 요소요소는 대기열에 들어가고 tail의 위치를 ​​유지하며 tail++ 작업을 수행합니다.

요소는 대기열에서 제외되고 의 위치를 ​​유지합니다. front를 수행하고 front++를 수행합니다. 위에서 언급한 것처럼 요소가 대기열에 추가되고 대기열에서 제거될 때 ++ 작업은 단순히 tailfront입니다. 예, 꼬리를 유지하기 위한 올바른 위치는 (tail + 1)% 용량이어야 합니다. 마찬가지로 앞쪽 위치도 (front + 1)% 용량이어야 합니다. 여기서부터 먼저 알아두세요. 지금은 이해하지 못하셔도 괜찮습니다. Java 순환 큐 소개(코드 예)

아래에서 a 요소가 대기열에 추가되면 현재 다이어그램을 살펴보겠습니다.

Java 순환 큐 소개(코드 예)

Java 순환 큐 소개(코드 예)이제 요소 a가 대기열에 추가되고 꼬리가 가리키는 위치가 변경되었으며 ++ 연산이 수행되었으며 front 의 위치는 변경되지 않았으며 여전히 인덱스 0의 위치를 ​​가리킵니다. 작성자가 위에서 말한 것을 기억하세요. front 의 위치는 항상 대기열의 첫 번째 요소를 가리키고 tail 의 위치는 항상 다음 요소를 가리킵니다. 위치

이제 대기열에 합류하기 위해 몇 가지 요소 b, c, d 및 e를 추가해 보겠습니다.

🎜🎜Java 순환 큐 소개(코드 예)🎜🎜모두가 알고 있다고 믿습니다 회로도가 이렇다고 해서 변경 사항은 많지 않은 것 같습니다. (또한 문의해 주세요. 걱정하지 마세요. 여러분, 이것은 순환 대기열이 무엇인지 모두가 이해하기 위한 것입니다. 양해해 주시기 바랍니다. O(∩_∩)O !)🎜🎜🎜큐에 요소를 추가하는 작업을 읽은 후, 이제 요소의 대기열 제거 작업이 어떻게 생겼는지 살펴보겠습니다. 🎜🎜🎜요소 a가 대기열에서 제거되었습니다. 회로도는 다음과 같습니다. 🎜🎜🎜🎜🎜이제 요소 a가 대기열에서 제거되었으며 전면 위치는 인덱스 1의 위치를 ​​가리킵니다. 한 위치 앞으로 이동 🎜🎜이것은 배열 대기열과 완전히 다릅니다(배열 대기열에서는 요소를 대기열에서 빼야 하며 후속 요소는 한 위치 앞으로 이동해야 합니다). 이전 O(n) 연산에서 O(1) 연산이 되었습니다🎜🎜🎜요소 b를 다시 대기열에서 제거합니다. 회로도는 다음과 같습니다.🎜🎜🎜🎜🎜🎜이 시점에서 몇몇 친구들은 왜 순환 대기열이라고 불리는지 물어볼 수도 있습니다. 이제 시도해 보겠습니다. 요소 f와 g를 각각 대기열에 추가합니다. 이때 다이어그램은 다음과 같습니다. 🎜🎜🎜🎜🎜🎜 이때 육안 검사에서는 여전히 변화가 없습니다. 요소 h 큐 작업에 참여하면 다음과 같은 질문이 발생합니다. 꼬리의 위치를 ​​어떻게 지정해야 합니까? 개략도는 다음과 같습니다. 🎜

Java 순환 큐 소개(코드 예)

앞서 말한 대로 요소 인큐: tail의 위치를 ​​유지하고 tail++ 연산을 수행합니다. 이때 tail은 인덱스 7의 위치를 ​​가리킵니다. 이때 tail에 ++ 연산을 수행하면 됩니다. , 분명히 불가능합니다(범위를 벗어난 배열)

조심스러운 친구들은 현재 대기열이 가득 차지 않았으며 여전히 두 자리가 남아 있다는 것을 알게 될 것입니다(이는 요소가 대기열에서 제거된 후에도 현재 공간이 후속 요소)), 배열을 링으로 상상하면 인덱스 7 이후의 위치는 인덱스 0

인덱스 7 위치에서 인덱스 0 위치까지 어떻게 계산할 수 있습니까? 이전에 tail++ 연산에 대해 이야기했습니다. , 그리고 저자도 처음에 지적했듯이 이것은 (tail + 1) % 용량이어야 하며 이는 (7 + 1) % 8이 0

이 됩니다. 따라서 요소 h가 추가되면 이때 꼬리는 인덱스 0의 위치를 ​​가리킵니다. 개략도는 다음과 같습니다.

Java 순환 큐 소개(코드 예)

이제 새 요소 k가 큐에 추가된다고 가정하면 꼬리의 위치는 다음과 같습니다. (꼬리 + 1) % 용량, 즉 (0 + 1) % 8은 1과 같고 인덱스 1의 위치를 ​​가리킵니다

Java 순환 큐 소개(코드 예)

그러면 문제는 순환 대기열이 여전히 요소를 대기열에 넣을 수 있느냐는 것입니다. 이를 분석해 보면, 이전 논리에 따르면 이제 새 요소를 넣을 수 있다고 가정할 때 인덱스가 0인 빈 공간 위치가 여전히 남아 있음을 알 수 있습니다. , tail (tail +1) % 용량 계산을 수행하고 결과는 2입니다(요소가 대기열에 성공적으로 추가된 경우 현재 대기열은 가득 찼습니다). 이때 앞쪽이 head를 나타내는 것을 알 수 있습니다. 큐도 인덱스 2의 위치를 ​​가리킵니다

새 요소가 큐에 성공적으로 합류하면 tail도 2가 되고 tail == front가 됩니다. 처음에 큐가 다음과 같다고 언급했습니다. 비어 있음, tail == front. 이제 큐가 가득 차면 tail도 앞과 같으므로 큐가 가득 찼을 때의 컬렉션과 큐가 비어 있을 때의 컬렉션을 구별할 수 없습니다

따라서 순환 큐에서는 항상 큐가 가득 찼을 때와 큐가 비어 있을 때를 구별하기 위해 공간을 낭비합니다. 즉, (tail + 1) % 용량 == front인 경우 큐가 가득 찼음을 의미하고 front == tail인 경우를 의미합니다. , 이는 대기열이 비어 있음을 의미합니다.

Java 순환 큐 소개(코드 예)

순환 큐의 구현 원리를 이해한 후 코드로 구현해 보겠습니다.

코드 구현

인터페이스 정의: Queue

public interface Queue<e> {
    /**
     * 入队
     *
     * @param e
     */
    void enqueue(E e);

    /**
     * 出队
     *
     * @return
     */
    E dequeue();

    /**
     * 获取队首元素
     *
     * @return
     */
    E getFront();

    /**
     * 获取队列中元素的个数
     *
     * @return
     */
    int getSize();

    /**
     * 判断队列是否为空
     *
     * @return
     */
    boolean isEmpty();
}</e>
로그인 후 복사

인터페이스 구현: LoopQueue

public class LoopQueue<e> implements Queue<e> {
    /**
     * 承载队列元素的数组
     */
    private E[] data;
    /**
     * 队首的位置
     */
    private int front;
    /**
     * 队尾的位置
     */
    private int tail;
    /**
     * 队列中元素的个数
     */
    private int size;

    /**
     * 指定容量,初始化队列大小
     * (由于循环队列需要浪费一个空间,所以我们初始化队列的时候,要将用户传入的容量加1)
     *
     * @param capacity
     */
    public LoopQueue(int capacity) {
        data = (E[]) new Object[capacity + 1];
    }

    /**
     * 模式容量,初始化队列大小
     */
    public LoopQueue() {
        this(10);
    }


    @Override
    public void enqueue(E e) {
        // 检查队列为满
        if ((tail + 1) % data.length == front) {
            // 队列扩容
            resize(getCapacity() * 2);
        }
        data[tail] = e;
        tail = (tail + 1) % data.length;
        size++;
    }


    @Override
    public E dequeue() {
        if (isEmpty()) {
            throw new IllegalArgumentException("队列为空");
        }
        // 出队元素
        E element = data[front];
        // 元素出队后,将空间置为null
        data[front] = null;
        // 维护front的索引位置(循环队列)
        front = (front + 1) % data.length;
        // 维护size大小
        size--;

        // 元素出队后,可以指定条件,进行缩容
        if (size == getCapacity() / 2 && getCapacity() / 2 != 0) {
            resize(getCapacity() / 2);
        }
        return element;
    }

    @Override
    public E getFront() {
        if (isEmpty()) {
            throw new IllegalArgumentException("队列为空");
        }
        return data[front];
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return front == tail;
    }


    // 队列快满时,队列扩容;元素出队操作,指定条件可以进行缩容
    private void resize(int newCapacity) {
        // 这里的加1还是因为循环队列我们在实际使用的过程中要浪费一个空间
        E[] newData = (E[]) new Object[newCapacity + 1];
        for (int i = 0; i <p>테스트 클래스: LoopQueueTest</p>
<pre class="brush:php;toolbar:false">public class LoopQueueTest {
    @Test
    public void testLoopQueue() {
        LoopQueue<integer> loopQueue = new LoopQueue();
        for (int i = 0; i <p>테스트 결과: </p>
<pre class="brush:php;toolbar:false">原始队列: LoopQueue{【队首】data=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, null]【队尾】, front=0, tail=10, size=10, capacity=10}
元素0出队: LoopQueue{【队首】data=[null, 1, 2, 3, 4, 5, 6, 7, 8, 9, null]【队尾】, front=1, tail=10, size=9, capacity=10}
元素1出队: LoopQueue{【队首】data=[null, null, 2, 3, 4, 5, 6, 7, 8, 9, null]【队尾】, front=2, tail=10, size=8, capacity=10}
元素2出队: LoopQueue{【队首】data=[null, null, null, 3, 4, 5, 6, 7, 8, 9, null]【队尾】, front=3, tail=10, size=7, capacity=10}
元素3出队: LoopQueue{【队首】data=[null, null, null, null, 4, 5, 6, 7, 8, 9, null]【队尾】, front=4, tail=10, size=6, capacity=10}
元素4出队,发生缩容: LoopQueue{【队首】data=[5, 6, 7, 8, 9, null]【队尾】, front=0, tail=5, size=5, capacity=5}
队首元素:5
로그인 후 복사
전체 버전 코드 GitHub 창고 주소:
Java 버전 데이터 구조 - 큐(원형 큐)

이 기사는 여기서 끝났습니다. 더 흥미로운 콘텐츠를 보려면 PHP 중국어 웹사이트의

Java Video Tutorial

칼럼을 주목하세요!




위 내용은 Java 순환 큐 소개(코드 예)의 상세 내용입니다. 자세한 내용은 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 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

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

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

자바의 완전수 자바의 완전수 Aug 30, 2024 pm 04:28 PM

Java의 완전수 가이드. 여기서는 정의, Java에서 완전 숫자를 확인하는 방법, 코드 구현 예제에 대해 논의합니다.

자바의 웨카 자바의 웨카 Aug 30, 2024 pm 04:28 PM

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 스미스 번호 Java의 스미스 번호 Aug 30, 2024 pm 04:28 PM

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

Java Spring 인터뷰 질문 Java Spring 인터뷰 질문 Aug 30, 2024 pm 04:29 PM

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Feb 07, 2025 pm 12:09 PM

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 날짜까지의 타임스탬프 Java의 날짜까지의 타임스탬프 Aug 30, 2024 pm 04:28 PM

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

캡슐의 양을 찾기위한 Java 프로그램 캡슐의 양을 찾기위한 Java 프로그램 Feb 07, 2025 am 11:37 AM

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

미래를 창조하세요: 완전 초보자를 위한 Java 프로그래밍 미래를 창조하세요: 완전 초보자를 위한 Java 프로그래밍 Oct 13, 2024 pm 01:32 PM

Java는 초보자와 숙련된 개발자 모두가 배울 수 있는 인기 있는 프로그래밍 언어입니다. 이 튜토리얼은 기본 개념부터 시작하여 고급 주제를 통해 진행됩니다. Java Development Kit를 설치한 후 간단한 "Hello, World!" 프로그램을 작성하여 프로그래밍을 연습할 수 있습니다. 코드를 이해한 후 명령 프롬프트를 사용하여 프로그램을 컴파일하고 실행하면 "Hello, World!"가 콘솔에 출력됩니다. Java를 배우면 프로그래밍 여정이 시작되고, 숙달이 깊어짐에 따라 더 복잡한 애플리케이션을 만들 수 있습니다.

See all articles