Thuta Learning
Data Structures & Algorithms
IntermediateProgrammingintermediate

Doubly Linked List နဲ့ Python ရဲ့ deque

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Doubly Linked List နဲ့ Python ရဲ့ deque concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ Python code ကို ကိုယ်တိုင် run ပြီး output စစ်နိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

Singly linked list မှာ node တစ်ခုစီက next ကိုပဲ ညွှန်ပြတယ်၊ ဒါကြောင့် list ရဲ့ အဆုံးက element ကို ဖြုတ်ချင်ရင်တောင် head ကနေ traverse လုပ်ပြီး ရှေ့ node ကို ရှာနေရတယ် — O(n)။ Doubly linked list ကတော့ node တစ်ခုစီမှာ next အပြင် prev ကိုပါ ထည့်ညွှန်ပြထားလို့၊ node ဘယ်နေရာမှာရှိရှိ ဘေးက node ကို O(1) နဲ့ တိုက်ရိုက် ရောက်နိုင်တယ်၊ ဒါကြောင့် list ရဲ့ ရှေ့ဘက်ကနေရော နောက်ဘက်ကနေရော ဖြုတ်/ထည့် တာ O(1) ဖြစ်တယ်။ Python မှာ ဒီဖွဲ့စည်းပုံကို ကိုယ်တိုင် implement လုပ်ဖို့ မလိုပါဘူး — `collections.deque` (double-ended queue) ဟာ doubly linked list ကို base ခံပြီး ရေးထားတာဖြစ်လို့ `append`, `appendleft`, `pop`, `popleft` အားလုံးကို O(1) နဲ့ လုပ်ပေးတယ်။ ဒါကြောင့် ဘေးနှစ်ဖက်စလုံးက ဖြည့်/ဖြုတ်ဖို့ လိုအပ်တဲ့ queue, stack, sliding-window, recent-history ကဲ့သို့ use case တွေမှာ plain list ထက် deque က theoretically ပိုမှန်ကန်တဲ့ ရွေးချယ်မှုဖြစ်တယ်။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Tutorial Platform ရဲ့ 'Recently Viewed Lessons' panel ကို `deque` နဲ့ တည်ဆောက်နိုင်တယ် — user က lesson အသစ် ဖွင့်တိုင်း `appendleft()` နဲ့ ရှေ့ဆုံးမှာ ထည့်ပြီး၊ `maxlen` သတ်မှတ်ထားလို့ အဟောင်းဆုံး entry က အလိုအလျောက် ဘေးက ကျသွားတယ်၊ ဒါအားလုံး O(1)။

အတူတူ စမ်းရေးကြည့်မယ်

python
from collections import deque

# deque is a doubly linked list under the hood, so both ends are O(1)
recent_lessons = deque(maxlen=3)

recent_lessons.append("intro")        # add to right end - O(1)
recent_lessons.append("variables")
recent_lessons.appendleft("welcome")  # add to left end - O(1), no shifting
print(list(recent_lessons))

recent_lessons.pop()      # remove from right end - O(1)
recent_lessons.popleft()  # remove from left end - O(1)
print(list(recent_lessons))

# Contrast: a plain list's pop(0) is O(n) because every remaining
# element must shift left by one to fill the gap.
You should see
ပထမဆုံး print က `['welcome', 'intro', 'variables']` ကို ပြပြီး၊ pop() နဲ့ popleft() နှစ်ခု ခေါ်ပြီးနောက် ဒုတိယ print က `['intro']` ကို ပြတယ်။

၅ မိနစ် စမ်းကြည့်

Plain Python list တစ်ခုနဲ့ ကုတ်ကို ပြန်ရေးပြီး `insert(0, ...)` နဲ့ `pop(0)` သုံးကြည့်ပါ၊ result တူပေမယ့် element အရေအတွက်များလာရင် ဘာကြောင့် နှေးလာမလဲ စဉ်းစားပါ။

သတိလေးတစ်ချက်

Recent-history buffer ကို plain list နဲ့ implement လုပ်ပြီး `list.insert(0, item)` သုံးတတ်တယ် — element တစ်ခုစီ shift ဖြစ်ရလို့ O(n) ဖြစ်သွားတယ်

`deque`ကို random access (`d[5]`) များများသုံးမယ်ဆိုရင် linked structure ဖြစ်လို့ middle index ကို ရောက်ဖို့ O(n) ကြာနိုင်တယ်—array လို O(1) မဟုတ်ဘူး

Python Docs — collections.dequeData Structures & Algorithms

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Recent-history buffer ကို plain list နဲ့ implement လုပ်ပြီး `list.insert(0, item)` သုံးတတ်တယ် — element တစ်ခုစီ shift ဖြစ်ရလို့ O(n) ဖြစ်သွားတယ်
  • `deque`ကို random access (`d[5]`) များများသုံးမယ်ဆိုရင် linked structure ဖြစ်လို့ middle index ကို ရောက်ဖို့ O(n) ကြာနိုင်တယ်—array လို O(1) မဟုတ်ဘူး
  • နမူနာ code ကို production system ပေါ် တိုက်ရိုက်မစမ်းဘဲ local/test environment တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

Plain Python list တစ်ခုနဲ့ ကုတ်ကို ပြန်ရေးပြီး `insert(0, ...)` နဲ့ `pop(0)` သုံးကြည့်ပါ၊ result တူပေမယ့် element အရေအတွက်များလာရင် ဘာကြောင့် နှေးလာမလဲ စဉ်းစားပါ။

You'll know it worked when: ပထမဆုံး print က `['welcome', 'intro', 'variables']` ကို ပြပြီး၊ pop() နဲ့ popleft() နှစ်ခု ခေါ်ပြီးနောက် ဒုတိယ print က `['intro']` ကို ပြတယ်။

Doubly Linked List နဲ့ Python ရဲ့ deque | Thuta Learning