0Pricing
Java Academy · บทเรียน

การทำงานของ Deque: สแตกและคิว

ใช้ LinkedList เป็น Deque เพื่อทำงานแบบสแตก (push/pop) และคิว (offer/poll)

การทำงานของ Deque: สแตกและคิว เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คิวสองทาง: คิวปลายคู่

คิวสองทาง อนุญาตให้เพิ่มและนำรายการออกจากปลายทั้งสองด้านได้ Java's Deque interface ถูกใช้งานโดย LinkedList และ ArrayDeque

import java.util.Deque;
import java.util.ArrayDeque;

Deque<String> deque = new ArrayDeque<>();
deque.addFirst("A"); // front
deque.addLast("B");  // back
deque.addFirst("Z"); // new front

System.out.println(deque); // [Z, A, B]

ArrayDeque เทียบกับ LinkedList ในฐานะคิวสองทาง

โดยทั่วไปควรเลือก ArrayDeque มากกว่า LinkedList เมื่อใช้เป็นคิวสองทาง:

  • ไม่มีค่าใช้หน่วยความจำของโหนดแยกสำหรับแต่ละองค์ประกอบ
  • ตำแหน่งข้อมูลในแคชดีกว่า
  • เร็วกว่าเล็กน้อยสำหรับการดำเนินการแบบสแตกหรือคิว

เลือก LinkedList ก็ต่อเมื่อคุณต้องใช้ List interface ด้วย

การดำเนินการแบบสแตกด้วยคิวสองทาง

ใช้ push (addFirst) และ pop (removeFirst) เพื่อจำลองสแตกแบบ LIFO หลีกเลี่ยงคลาส Stack รุ่นเก่า เพราะมีการซิงโครไนซ์และล้าสมัยแล้ว

Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
stack.push(2);
stack.push(3);

System.out.println(stack.pop());  // 3
System.out.println(stack.peek()); // 2 (no removal)
System.out.println(stack.pop());  // 2

การดำเนินการแบบคิวด้วยคิวสองทาง

ใช้ offer (addLast) และ poll (removeFirst) เพื่อจำลองคิวแบบ FIFO โดย offer จะคืนค่า false เมื่อล้มเหลว ส่วน add จะส่งข้อผิดพลาด

Deque<String> queue = new ArrayDeque<>();
queue.offer("task1");
queue.offer("task2");
queue.offer("task3");

System.out.println(queue.poll());  // task1
System.out.println(queue.poll());  // task2
System.out.println(queue.size());  // 1

ตารางอ้างอิงเมธอดของคิวสองทาง

คิวสองทางมีเมธอดสองกลุ่ม — กลุ่มหนึ่งส่งข้อผิดพลาด อีกกลุ่มคืนค่าพิเศษ:

  • addFirst/addLast เทียบกับ offerFirst/offerLast
  • removeFirst/removeLast เทียบกับ pollFirst/pollLast
  • getFirst/getLast เทียบกับ peekFirst/peekLast

ควรใช้กลุ่ม offer/poll/peek เพื่อหลีกเลี่ยงข้อผิดพลาดเมื่อคิวสองทางว่าง

ตัวอย่างจริง: ยกเลิกทำและทำซ้ำด้วยสแตกสองชุด

กรณีใช้งานคิวสองทางที่คลาสสิก: ประวัติการยกเลิกการทำงานเป็นสแตก ส่วนการทำซ้ำเป็นอีกสแตกหนึ่ง

Deque<String> undo = new ArrayDeque<>();
Deque<String> redo = new ArrayDeque<>();

undo.push("type 'Hello'");
undo.push("type ' World'");

String action = undo.pop();
System.out.println("Undone: " + action); // type ' World'
redo.push(action);

System.out.println("Redo top: " + redo.peek()); // type ' World'

การตรวจสอบพาลินโดรมด้วยคิวสองทาง

คิวสองทางทำให้การตรวจสอบพาลินโดรมกระชับและเข้าใจง่าย — เปรียบเทียบอักขระจากปลายทั้งสองด้านพร้อมกัน

Deque<Character> deque = new ArrayDeque<>();
for (char c : "racecar".toCharArray()) deque.add(c);

boolean isPalindrome = true;
while (deque.size() > 1) {
    if (!deque.pollFirst().equals(deque.pollLast())) {
        isPalindrome = false;
        break;
    }
}
System.out.println(isPalindrome); // true

BFS ด้วยคิว

การค้นหาแบบกว้างใช้คิว ArrayDeque เป็นตัวเลือกมาตรฐานสำหรับ BFS ในการเขียนโปรแกรมแข่งขันและการท่องกราฟ

import java.util.*;

// BFS on a simple adjacency list
Map<Integer,List<Integer>> graph = Map.of(
    1, List.of(2,3),
    2, List.of(4),
    3, List.of(4),
    4, List.of()
);
Deque<Integer> queue = new ArrayDeque<>();
Set<Integer> visited = new HashSet<>();
queue.offer(1);
while (!queue.isEmpty()) {
    int node = queue.poll();
    if (visited.add(node)) {
        System.out.print(node + " ");
        queue.addAll(graph.get(node));
    }
}

DFS ด้วยสแตก

การค้นหาแบบลึกใช้สแตก และเช่นเดิมควรเลือก ArrayDeque แทนคลาส Stack รุ่นเก่า

Deque<Integer> stack = new ArrayDeque<>();
Set<Integer> visited = new HashSet<>();
stack.push(1);
while (!stack.isEmpty()) {
    int node = stack.pop();
    if (visited.add(node)) {
        System.out.print(node + " ");
        // push neighbors (will be processed in reverse order)
        List<Integer> neighbors = List.of(2, 3); // simplified
        for (int n : neighbors) if (!visited.contains(n)) stack.push(n);
    }
}

คิวสองทางแบบมีขอบเขตพร้อมตรวจสอบขนาด

ArrayDeque จะขยายขนาดแบบไดนามิก แต่คุณสามารถกำหนดความจุด้วยตนเองเพื่อจำลองบัฟเฟอร์แบบมีขอบเขตได้:

Deque<Integer> buffer = new ArrayDeque<>();
int MAX = 3;

for (int i = 1; i <= 5; i++) {
    if (buffer.size() >= MAX) {
        buffer.pollFirst(); // drop oldest
    }
    buffer.offerLast(i);
}
System.out.println(buffer); // [3, 4, 5]

หมายเหตุด้านประสิทธิภาพ

ArrayDeque ใช้อาร์เรย์แบบวงกลมซึ่งจะเพิ่มขนาดเป็นสองเท่าเมื่อเต็ม ต้นทุนตัดจำหน่ายของการดำเนินการทั้งหมดคือ O(1) และมีประสิทธิภาพดีกว่า LinkedList ในการทดสอบประสิทธิภาพส่วนใหญ่เนื่องจากใช้แคชได้ดี อย่าซิงโครไนซ์ด้วยตนเอง — ให้ใช้ ConcurrentLinkedDeque หรือคิวแบบบล็อกสำหรับการทำงานพร้อมกัน

ตรวจสอบความเข้าใจอย่างรวดเร็ว

คุณควรเลือกคลาสใดแทน Stack รุ่นเก่าสำหรับการดำเนินการแบบ LIFO

สรุป: การดำเนินการของคิวสองทาง

ประเด็นสำคัญ:

  • คิวสองทางอนุญาตให้เพิ่มหรือนำรายการออกจากปลายทั้งสองด้านได้ใน O(1)
  • ควรเลือก ArrayDeque แทน LinkedList สำหรับการใช้งานเป็นสแตกหรือคิวโดยเฉพาะ
  • push/pop → สแตกแบบ LIFO; offer/poll → คิวแบบ FIFO
  • การใช้งานคลาสสิก: ยกเลิกทำและทำซ้ำ, BFS/DFS, หน้าต่างเลื่อน, การตรวจสอบพาลินโดรม
  • หลีกเลี่ยงคลาสสแตกและคิวรุ่นเก่า

คำถามที่พบบ่อย

บทเรียน “การทำงานของ Deque: สแตกและคิว” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การทำงานของ Deque: สแตกและคิว” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การทำงานของ Deque: สแตกและคิว”

ใช้ LinkedList เป็น Deque เพื่อทำงานแบบสแตก (push/pop) และคิว (offer/poll) คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การทำงานของ Deque: สแตกและคิว” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครงสร้างภายในของ LinkedList
  2. การทำงานของ Deque: สแตกและคิว
  3. ข้อแลกเปลี่ยนระหว่าง LinkedList กับ ArrayList
  4. PriorityQueue สำหรับการประมวลผลตามลำดับ
← กลับไปที่ Java Academy