การทำงานของ 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); // trueBFS ด้วยคิว
การค้นหาแบบกว้างใช้คิว 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- โครงสร้างภายในของ LinkedList
- การทำงานของ Deque: สแตกและคิว
- ข้อแลกเปลี่ยนระหว่าง LinkedList กับ ArrayList
- PriorityQueue สำหรับการประมวลผลตามลำดับ