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

ឧបករណ៍មើល Array ក្នុង Memory

មើលធាតុ array ស្ថិតនៅក្បែរគ្នាក្នុង memory រំកិលពេលបញ្ចូល និងលុប ហើយប្តូរទីតាំងពេល array ពង្រីកទំហំ។

Length: 0 Capacity: 0 Element size: 4 bytes Element moves: 0
  • Reading
  • Writing
  • Found or new
  • Free capacity
Step 1 of 1

get(i):  address = base + i × elementSize  return memory[address]            // O(1)append(x):  if length = capacity: grow()  a[length] = x; length = length + 1insert(i, x):  if length = capacity: grow()  for k = length − 1 down to i    a[k + 1] = a[k]                  // shift right  a[i] = x; length = length + 1delete(i):  for k = i to length − 2    a[k] = a[k + 1]                  // shift left  length = length − 1grow():  newBlock = allocate(capacity × 2)  copy a[0 .. length − 1] to newBlock  free the old block; a = newBlocksearch(x):  for i = 0 to length − 1: if a[i] = x: return i  return −1
Dynamic array operations
OperationTime
Access a[i]O(1)
AppendO(1) amortized, O(n) when it grows
Insert at indexO(n)
Delete at indexO(n)
Search (unsorted)O(n)
Search (sorted, binary)O(log n)
SpaceO(n), up to 2n with doubling

Array គឺជារចនាសម្ព័ន្ធទិន្នន័យដ៏សាមញ្ញបំផុត៖ ជាប្លុក memory មួយដែលធាតុនីមួយៗមានទំហំស្មើគ្នា និងស្ថិតនៅបន្ទាប់ពីធាតុមុនភ្លាមៗ។ ឧបករណ៍ visualizer នេះគូរប្លុកនោះជាជួរនៃក្រឡា memory ដែលមាន index តម្លៃ និងអាសយដ្ឋាន memory ពិតរបស់វា។ ជ្រើសរើសប្រភេទធាតុដូចជា int (4 bytes), long ឬ double (8 bytes) ឬ char (1 byte) ព្រមទាំង base address នោះអ្នកនឹងឃើញអាសយដ្ឋាននីមួយៗប្តូរទៅជា base + index × size។

បន្ទាប់មក សាកល្បងប្រតិបត្តិការផ្សេងៗ។ ការចូលប្រើ a[i] ប្រើតែមួយជំហានប៉ុណ្ណោះ ព្រោះអាសយដ្ឋានត្រូវបានគណនា មិនមែនស្វែងរកនោះទេ។ ការបញ្ចូល ឬលុបនៅចំកណ្តាលនឹងរំកិលធាតុបន្ទាប់ទាំងអស់មួយក្រឡា ដែលជាមូលហេតុធ្វើឱ្យប្រតិបត្តិការទាំងនោះជា O(n)។ បន្ថែមធាតុទៅចុង array ដែលពេញ អ្នកនឹងឃើញអ្វីដែល dynamic array (ArrayList ក្នុង Java, std::vector ក្នុង C++, list ក្នុង Python) ធ្វើ៖ គឺវាបម្រុងទុកប្លុកថ្មីធំជាងមុនពីរដង ចម្លងធាតុទាំងអស់ទៅ ហើយលុបប្លុកចាស់ចោល។

របៀបប្រើឧបករណ៍ ឧបករណ៍មើល Array ក្នុង Memory

  1. ជ្រើសរើស ប្រភេទធាតុ ហើយប្រសិនបើអ្នកចង់ អាចប្តូរ base address ជាលេខ hex។
  2. វាយបញ្ចូល តម្លៃ និង index បន្ទាប់មកចុច ចូលប្រើ a[i], បន្ថែមនៅចុង, បញ្ចូលតាម index, លុបតាម index ឬ ស្វែងរកតម្លៃ។
  3. មើលចលនា animation។ ក្រឡាពណ៌ទឹកក្រូចកំពុងត្រូវបានអាន ក្រឡាពណ៌ក្រហមកំពុងត្រូវបានសរសេរ ហើយក្រឡាពណ៌បៃតងផ្ទុកតម្លៃថ្មី ឬតម្លៃដែលរកឃើញ។
  4. ប្រើ ជំហានបន្ទាប់ (Step) និង ថយក្រោយ (Back) ដើម្បីមើលការរំកិល ឬការប្តូរទំហំម្តងមួយធាតុ ហើយអានរូបមន្តអាសយដ្ឋាននៅខាងក្រោមកោសិកា។
  5. បន្តបន្ថែមធាតុរហូតដល់ array ពេញ ដើម្បីមើលទំហំ capacity កើនឡើងទ្វេដង និងធាតុត្រូវបានចម្លងទៅប្លុកថ្មី។

ហេតុអ្វីប្រើ ឧបករណ៍មើល Array ក្នុង Memory របស់ ToolOrca

  • ក្រឡា memory បង្ហាញ index តម្លៃ និងអាសយដ្ឋាន hexadecimal
  • ទំហំធាតុប្រភេទ int, long, char និង double
  • រូបមន្តអាសយដ្ឋានបង្ហាញសម្រាប់ការចូលប្រើម្តងៗ
  • ចលនារំកិលធាតុពេលបញ្ចូល និងលុប
  • ការពង្រីក capacity ទ្វេដងដោយចម្លងទៅប្លុកថ្មី
  • ឧបករណ៍រាប់ប្រវែង (length), ចំណុះ (capacity) និងចំនួនរំកិលធាតុ
  • កូដសម្រាប់ dynamic array ជា C++, Java, Python និង JavaScript

របៀបដែល array ត្រូវបានផ្ទុកក្នុង memory

នៅពេលកម្មវិធីបង្កើត array វានឹងស្នើសុំប្លុក memory ជាប់គ្នាមួយដែលធំល្មមសម្រាប់ធាតុទាំងអស់។ ប្រសកាលណា ប្លុកចាប់ផ្តើមនៅ base address B ហើយធាតុនីមួយៗប្រើ S bytes នោះធាតុទី i ស្ថិតនៅ B + i × S។ Array ប្រភេទ int ចាប់ផ្តើមពី 0x1000 ដាក់ a[0] នៅ 0x1000, a[1] នៅ 0x1004 និង a[5] នៅ 0x1014។ នេះជាមូលហេតុដែល index របស់ array ចាប់ផ្តើមពី 0 ក្នុង C, C++, Java, Python និង JavaScript៖ index គ្រាន់តែជាចម្ងាយពីចំណុចចាប់ផ្តើមប៉ុណ្ណោះ។

ដោយសារអាសយដ្ឋានជាការគណនា ការអាន ឬសរសេរលើធាតុណាមួយចំណាយពេលតិចតួចស្មើគ្នា ទោះបី array ធំប៉ុនណាក៏ដោយ។ នោះហើយជា O(1) random access ដែលជាគុណសម្បត្តិធំរបស់ array លើ linked list។ ធាតុដែលនៅក្បែរគ្នាក៏ត្រូវបានទាញចូលក្នុង CPU cache ជាមួយគ្នាផងដែរ ដូច្នេះការ loop កាត់ array គឺលឿនខ្លាំងក្នុងការអនុវត្តជាក់ស្តែង។

ការបញ្ចូល ការលុប និង dynamic array

គ្មានចន្លោះទំនេរនៅក្នុង array ទេ ដូច្នេះការបញ្ចូលនៅ index i មានន័យថាត្រូវរំកិលធាតុទាំងអស់ពី i ដល់ចុងបញ្ចប់មួយជំហានទៅស្តាំសិន ហើយការលុបមានន័យថាត្រូវរំកិលពួកវាត្រឡប់មកឆ្វេងវិញ។ ក្នុងករណីអាក្រក់បំផុត (index 0) គឺត្រូវរំកិល n ដង ដូច្នេះការបញ្ចូល និងលុបគឺ O(n)។ ការបន្ថែម ឬដកចេញនៅខាងចុងមិនត្រូវការរំកិលទេ ហើយជា O(1)។

Fixed array មិនអាចពង្រីកបានទេ ព្រោះ memory បន្ទាប់ពីវាអាចជារបស់ទិន្នន័យផ្សេងទៀត។ Dynamic array ដោះស្រាយបញ្ហានេះដោយរក្សាទុក capacity បម្រុងខ្លះ។ នៅពេលវាពេញ វានឹងបម្រុងទុកប្លុកថ្មី ដែលជាទូទៅធំជាងមុន 1.5 ឬ 2 ដង រួចចម្លងទិន្នន័យទាំងអស់ ហើយលុបប្លុកចាស់ចោល។ ការចម្លង n ធាតុមានតម្លៃថ្លៃ ប៉ុន្តែវាកើតឡើងកម្រណាស់ ធ្វើឱ្យតម្លៃមធ្យម (amortized) នៃការ append នៅតែជា O(1)។ តារាង complexity ខាងក្រោម visualizer បង្ហាញសង្ខេបអំពីគ្រប់ប្រតិបត្តិការ។

ពេលណាគួរប្រើ array

ប្រើ array (ឬ dynamic array) នៅពេលអ្នកត្រូវការចូលប្រើរហ័សតាមទីតាំង កាលណាអ្នកបន្ថែមនៅខាងចុងជាចម្បង និងនៅពេលអ្នក loop លើទិន្នន័យញឹកញាប់។ ជ្រើសរើស linked list ជំនួសវិញតែនៅពេលអ្នកបញ្ចូល និងលុបនៅចំកណ្តាលញឹកញាប់ ហើយមាន pointer ទៅកាន់ទីតាំងនោះរួចជាស្រេច ឬនៅពេលដែលធាតុមិនត្រូវផ្លាស់ទីក្នុង memory ដាច់ខាត។

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

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

តើត្រូវគណនាអាសយដ្ឋាននៃធាតុ array យ៉ាងដូចម្តេច?

អាសយដ្ឋាននៃ a[i] = base address + i × ទំហំធាតុ។ សម្រាប់ int array (4 bytes) ចាប់ផ្តើមពី 0x1000 នោះ a[3] ស្ថិតនៅ 0x1000 + 3 × 4 = 0x100C។

ហេតុអ្វីការចូលប្រើ array គឺ O(1)?

ព្រោះកុំព្យូទ័រគណនាអាសយដ្ឋានដោយប្រើតែវិធីគុណមួយ និងវិធីបូកមួយ។ វាមិនចាំបាច់ឆ្លងកាត់ធាតុមុនៗនោះទេ ដូច្នេះពេលវេលាមិនអាស្រ័យលើទំហំរបស់ array ឡើយ។

ហេតុអ្វីការបញ្ចូល និងលុបក្នុង array គឺ O(n)?

ធាតុត្រូវតែនៅជាប់គ្នា ដូច្នេះគ្រប់ធាតុបន្ទាប់ពីទីតាំងនោះត្រូវតែរំកិលមួយកន្លែង។ ការបញ្ចូលនៅខាងមុខនៃ array ដែលមាន n ធាតុ ត្រូវរំកិលធាតុទាំង n នោះ។

តើមានអ្វីកើតឡើងនៅពេល dynamic array ពេញ?

វានឹងបម្រុងទុកប្លុកធំជាងមុន (ជាទូទៅទ្វេដងនៃ capacity) ចម្លងធាតុទាំងអស់ចូលទៅ ហើយលុបប្លុកចាស់ចោល។ ដោយសាររឿងនេះកើតឡើងកម្រ ការ append នៅតែជា O(1) ជាមធ្យម ដែលហៅថា amortized O(1)។

តើ length និង capacity ខុសគ្នាយ៉ាងដូចម្តេច?

Length គឺជាចំនួនធាតុដែលកំពុងផ្ទុកជាក់ស្តែង។ Capacity គឺជាចំនួនធាតុដែលអាចផ្ទុកបានក្នុងប្លុកបច្ចុប្បន្ន មុនពេលវាត្រូវពង្រីកទំហំ។ Vector ដែលមាន length 5 និង capacity 8 គឺមានកន្លែងទំនេរ 3។