Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม

การดำเนินการของ Meldable Priority Queue


ภาพรวม

Randomized Meldable Heap (หรือ Meldable Priority Queue) รองรับการดำเนินการทั่วไป ได้แก่ Insertion, Deletion, และ FindMin การแทรกและลบถูกนำไปใช้ในรูปของการดำเนินการเพิ่มเติมที่เฉพาะเจาะจงคือ Meld(A1, A2)

Meld (Merge)

เป้าหมายคือรับสองฮีป (ผ่านรูทโหนด) A1 และ A2 รวมกัน คืนค่าโหนดรูทเดียวเป็นผลลัพธ์ โหนดรูทนี้เป็นรูทของฮีปที่มีทุกองค์ประกอบจากซับทรีสองตัวที่รูทอยู่ที่ A1 และ A2

จุดเด่น: สามารถนิยามได้แบบ Recursive (เรียกซ้ำ)

อัลกอริทึม

function Meld(Node A1, Node A2)
  if A1 is nil => return A2
  if A2 is nil => return A1
  if A1 > A2 => swap A1 and A2
  // ตอนนี้ A1 < A2 รับประกันว่ารูทของฮีปที่รวมจะเป็น A1
  if coin_toss is 0 => A1.left = Meld(A1.left, A2)
  else              => A1.right = Meld(A1.right, A2)
  return A1

การตัดสินใจด้านไหนที่จะ merge นั้นสุ่มด้วยการทอยเหรียญ (Coin Toss) – นี่คือที่มาของ "Randomized"

Insert

เมื่อ Meld พร้อม Insert ก็ง่าย: สร้างโหนดใหม่ a ที่มีค่า p แล้ว merge กับรูทของฮีป

function Insert(p)
  Node a = new Node
  a.p = p
  root = Meld(a, root)
  root.parent = nil
  increment node count

Remove

เหมือน Insert ใช้ Meld เพื่อลบรูท: รวมลูกสองตัวของรูท แล้วทำให้โหนดที่คืนมาเป็นรูทใหม่

function Remove()
  rootNode = Meld(rootNode.left, rootNode.right)
  if rootNode is not nil => rootNode.parent = nil
  decrement node count

FindMin

การดำเนินการที่ง่ายที่สุด – คืนค่าองค์ประกอบที่เก็บอยู่ในรูทของฮีป

การดำเนินการเพิ่มเติม (O(log n) worst-case)

  • Remove(a) – ลบโหนด a และคีย์ของมันออกจากฮีป
  • Absorb(P) – รวมทุกองค์ประกอบของฮีป P เข้ามา ทำให้ P ว่าง
  • DecreaseKey(a, q) – ลดคีย์ในโหนด a เป็น q (เงื่อนไข: q ≤ a.p)