រំលងទៅមាតិកា

ឧបករណ៍មើល Doubly Linked List

Node នីមួយៗចង្អុលទៅទាំងសងខាង៖ មើល next និង prev pointers ផ្លាស់ប្តូរពេលបញ្ចូល លុប និង reverse។

View
Nodes: 0 Node size: 16 bytes Pointer steps: 0
  • Current node
  • New or found
  • Being deleted
  • Free memory

Each box is a node at its own memory address. The pointer field holds the address of the next node (and the previous one); the arrows show where it points.

Step 1 of 1

insertHead(v):  node = new Node(v)  node.next = head  if head ≠ null: head.prev = node  else: tail = node  head = nodeinsertTail(v):  node = new Node(v)  node.prev = tail  if tail ≠ null: tail.next = node  else: head = node  tail = nodeinsertAt(i, v):  if i = 0: insertHead(v); return  cur = head; repeat i − 1 times: cur = cur.next  node = new Node(v)  node.next = cur.next; node.prev = cur  if cur.next ≠ null: cur.next.prev = node else tail = node  cur.next = nodedelete(v):  cur = head  while cur ≠ null and cur.value ≠ v: cur = cur.next  if cur = null: return   // not found  if cur.prev ≠ null: cur.prev.next = cur.next else head = cur.next  if cur.next ≠ null: cur.next.prev = cur.prev else tail = cur.prev  free cursearch(v):  cur = head; i = 0  while cur ≠ null: if cur.value = v: return i    cur = cur.next; i = i + 1  return −1reverse():  cur = head  while cur ≠ null: swap cur.next and cur.prev    cur = cur.prev   // the old next  swap head and tail
Doubly linked list operations
OperationTime
Access by indexO(n)
SearchO(n)
Insert at headO(1)
Insert at tailO(1) with a tail pointer
Insert after a known nodeO(1)
Delete a known nodeO(1)
Extra memory per node2 pointers

នៅក្នុង doubly linked list គ្រប់ node ផ្ទុករបស់បីយ៉ាង៖ pointer ទៅកាន់ node មុន តម្លៃ និង pointer ទៅកាន់ node បន្ទាប់។ បញ្ជីនេះរក្សាទុកទាំង head និង tail pointer ដូច្នេះអ្នកអាចដើរទៅមកបានទាំងសងខាង និងបន្ថែមទៅចុងសងខាងក្នុងរយៈពេលថេរ។ ឧបករណ៍ visualizer នេះគូរ node នីមួយៗនៅអាសយដ្ឋាន memory របស់វាជាមួយ pointer fields ទាំងពីរ ព្រួញបន្ទាត់រឹងសម្រាប់ next និងព្រួញដាច់ៗពណ៌ស្វាយសម្រាប់ prev។

ដំណើរការប្រតិបត្តិការណាមួយ ហើយមើលឱ្យច្បាស់ថាតើ pointer ណាខ្លះផ្លាស់ប្តូរ និងតាមលំដាប់ណា៖ ការបញ្ចូលនៅចំកណ្តាលប៉ះពាល់ pointer បួន ការលុប node មិនបាច់ស្វែងរក node មុនទេ ហើយការ reverse គ្រាន់តែឆ្លាស់ next និង prev នៅក្នុង node នីមួយៗ។ ផ្ទាំងកូដ highlight តាមបន្ទាត់ pseudocode នីមួយៗ និងមានកូដពេញលេញជា C++, Java, Python និង JavaScript។

របៀបប្រើឧបករណ៍ ឧបករណ៍មើល Doubly Linked List

  1. វាយបញ្ចូល តម្លៃ និង index សម្រាប់ការបញ្ចូលតាម index។
  2. ជ្រើសរើសប្រតិបត្តិការ៖ បញ្ចូលនៅ head, tail ឬ index, លុបតម្លៃ, ស្វែងរកតម្លៃ ឬ reverse។
  3. មើលព្រួញ៖ ព្រួញខ្មៅរឹងគឺ next pointer ព្រួញពណ៌ស្វាយដាច់ៗគឺ prev pointer ពណ៌ក្រហមបង្ហាញ pointer ដែលទើបផ្លាស់ប្តូរ។
  4. ចុចទៅមុខ និងថយក្រោយមួយជំហានៗ ដើម្បីសិក្សាពីការអាប់ដេត pointer នីមួយៗ ឬប្តូរទៅទិដ្ឋភាព List order។

ហេតុអ្វីប្រើ ឧបករណ៍មើល Doubly Linked List របស់ ToolOrca

  • Node ដែលមាន prev, value និង next fields នៅអាសយដ្ឋានពិត
  • ព្រួញដាច់ដោយឡែកសម្រាប់ next និង prev pointers
  • បង្ហាញ Head និង tail pointers
  • O(1) សម្រាប់ការបញ្ចូលនៅចុងទាំងសងខាង
  • លុបដោយមិនបាច់ដើរស្វែងរក node មុន
  • Reverse ដោយគ្រាន់តែឆ្លាស់ pointers
  • Pseudocode និងកូដជាបួនភាសា

របៀបដែល doubly linked list ដំណើរការ

Node នីមួយៗមាន prev និង next pointers។ Node ដំបូងមាន prev ស្មើ NULL ហើយ node ចុងក្រោយមាន next ស្មើ NULL។ ដោយសារបញ្ជីរក្សាទុកទាំង tail pointer និង head ការបន្ថែម ឬដកចេញនៅចុងសងខាងចំណាយពេល O(1)៖ មិនចាំបាច់ដើររកនោះទេ។

Pointer បន្ថែមជួយឱ្យការលុបកាន់តែងាយស្រួល។ ក្នុង singly linked list អ្នកត្រូវការ node មុន node ដែលត្រូវលុប ដូច្នេះអ្នកត្រូវដើរជាមួយ prev pointer។ ក្នុង doubly linked list នោះ node ដឹងពីអ្នកជិតខាងរបស់វារួចហើយ៖ កំណត់ cur.prev.next = cur.next និង cur.next.prev = cur.prev នោះវានឹងដាច់ចេញពីបញ្ជី។

ការបញ្ចូលនៅចំកណ្តាល៖ pointers ចំនួនបួន

ដើម្បីបញ្ចូល node មួយបន្ទាប់ពី cur៖ កំណត់ node.next = cur.next និង node.prev = cur បន្ទាប់មក cur.next.prev = node (ឬ tail = node ប្រសិនបើនៅខាងចុង) ហើយចុងក្រោយ cur.next = node។ ការធ្វើខុសលំដាប់អាចធ្វើឱ្យបាត់បង់ផ្នែកខ្លះនៃបញ្ជី ដែលជាមូលហេតុធ្វើឱ្យ visualizer បង្ហាញការផ្លាស់ប្តូរ pointer នីមួយៗដាច់ដោយឡែកពីគ្នា។

ការ reverse doubly linked list គឺសាមញ្ញណាស់៖ ដើរកាត់បញ្ជី ហើយឆ្លាស់ next និង prev ក្នុង node នីមួយៗ បន្ទាប់មកឆ្លាស់ head និង tail។ វាប្រើពេល O(n) និងទំហំ O(1) បន្ថែម។

កន្លែងដែលគេប្រើ doubly linked list

Doubly linked list ត្រូវបានប្រើប្រាស់ក្នុង LRU caches (hash map បូក doubly linked list), ប្រវត្តិនៃ browser ទៅមុខថយក្រោយ (back/forward history), មុខងារ undo និង redo, music playlists និង class std::list និង LinkedList ក្នុង C++ និង Java។ គុណវិបត្តិគឺការប្រើ pointer បន្ថែមមួយក្នុង node នីមួយៗ និងការអាប់ដេត pointer ច្រើនជាងមុនបន្តិចក្នុងប្រតិបត្តិការម្តងៗ។

គ្រប់ visualizer នៅលើគេហទំព័រនេះដំណើរការក្នុង browser របស់អ្នកជាមួយប៊ូតុងបញ្ជាដូចគ្នា៖ ចាក់ (Play), ផ្អាក (Pause), ទៅមុខមួយជំហាន (Step), ថយក្រោយមួយជំហាន (Back) និងរបាររំកិលល្បឿន។ អ្នកក៏អាចអូសរបារទីតាំងដើម្បីផ្លាស់ទីទៅជំហានណាមួយ ឬចុចលើផ្ទាំងគំនូរហើយប្រើ Space bar និងគ្រាប់ចុចព្រួញ។

សំណួរដែលសួរញឹកញាប់

តើ singly និង doubly linked list ខុសគ្នាយ៉ាងណា?

Singly linked node មានតែ next pointer មួយប៉ុណ្ណោះ ដូច្នេះអ្នកអាចដើរទៅមុខបានតែមួយទិស។ Doubly linked node មាន prev pointer មួយទៀត ដូច្នេះអ្នកអាចដើរបានទាំងសងខាង និងលុប node ដោយមិនបាច់ស្វែងរក node ពីមុនវាឡើយ។

តើការលុបក្នុង doubly linked list គឺ O(1) មែនទេ?

ការលុប node ដែលអ្នកមាន pointer រួចហើយគឺ O(1)។ ប៉ុន្តែការស្វែងរក node តាមតម្លៃជាមុនសិន នៅតែជា O(n) ដដែល ព្រោះអ្នកត្រូវដើរស្វែងរកវា។

តើ doubly linked list ប្រើ memory បន្ថែមប៉ុន្មាន?

Pointer មួយបន្ថែមទៀតក្នុង node នីមួយៗ៖ 8 bytes លើប្រព័ន្ធ 64-bit។ សម្រាប់ទិន្នន័យតូចៗដូចជា int នោះ pointer អាចប្រើ memory ច្រើនជាងទិន្នន័យផ្ទាល់ទៅទៀត។

តើត្រូវ reverse doubly linked list យ៉ាងដូចម្តេច?

ឆ្លាស់ next និង prev pointer នៃគ្រប់ node បន្ទាប់មកឆ្លាស់ head និង tail pointer។