একটি পাঠের জন্য সময় ফিরে যেতে। যদিও আমরা আজ আমাদের অভিনব পরিচালিত ভাষাগুলিতে এই বিষয়গুলি সম্পর্কে খুব বেশি ভাবি না, সেগুলি একই ভিত্তিতে নির্মিত, সুতরাং আসুন দেখে নেওয়া যাক সিটিতে মেমরি কীভাবে পরিচালিত হয় at
আমি ডুব দেওয়ার আগে " পয়েন্টার " শব্দটির অর্থ কী তার একটি দ্রুত ব্যাখ্যা । একটি পয়েন্টার হ'ল একটি পরিবর্তনশীল যা স্মৃতিতে কোনও অবস্থানকে "পয়েন্ট" করে। এতে মেমরির এই অঞ্চলে আসল মান থাকে না, এতে এতে মেমরি ঠিকানা থাকে। মেলবক্স হিসাবে মেমরির একটি ব্লক ভাবেন। পয়েন্টারটি সেই মেলবক্সের ঠিকানা হবে।
সি তে, একটি অ্যারে কেবল অফসেট সহ একটি পয়েন্টার হয়, অফসেটটি স্মৃতিতে কতদূর যেতে হবে তা নির্দিষ্ট করে। এটি ও (1) অ্যাক্সেসের সময় সরবরাহ করে।
MyArray [5]
^ ^
Pointer Offset
অন্যান্য সমস্ত ডেটা স্ট্রাকচারগুলি এটির উপর ভিত্তি করে নির্মিত হয় বা স্টোরেজের জন্য সংলগ্ন মেমরি ব্যবহার করবেন না, ফলস্বরূপ এলোমেলো অ্যাক্সেসের সময় কম দেখা যায় (যদিও ক্রমযুক্ত মেমোরি ব্যবহার না করার অন্যান্য সুবিধা রয়েছে)।
উদাহরণস্বরূপ, ধরা যাক আমাদের এতে 6 টি সংখ্যা (6,4,2,3,1,5) সহ একটি অ্যারে রয়েছে, মেমরির ক্ষেত্রে এটি দেখতে দেখতে এটির মতো হবে:
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
একটি অ্যারে, আমরা জানি যে প্রতিটি উপাদান মেমরির একে অপরের পাশে থাকে। এসি অ্যারে ( MyArray
এখানে কল করা) কেবল প্রথম উপাদানটির জন্য পয়েন্টার:
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
^
MyArray
আমরা যদি সন্ধান করতে চাইতাম তবে MyArray[4]
অভ্যন্তরীণভাবে এটি এর মধ্যে প্রবেশ করা যেতে পারে:
0 1 2 3 4
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
^
MyArray + 4 ---------------/
(Pointer + Offset)
যেহেতু আমরা পয়েন্টারে অফসেট যুক্ত করে অ্যারেতে যে কোনও উপাদান সরাসরি অ্যাক্সেস করতে পারি, আমরা অ্যারের আকার নির্বিশেষে একই পরিমাণে যে কোনও উপাদান সন্ধান করতে পারি। এর অর্থ হ'ল প্রাপ্তি পাওয়া MyArray[1000]
সমান পরিমাণ সময় নেয় MyArray[5]
।
একটি বিকল্প ডেটা কাঠামো একটি লিঙ্কযুক্ত তালিকা। এটি পয়েন্টারগুলির একটি লিনিয়ার তালিকা, প্রতিটি পরবর্তী নোডের দিকে নির্দেশ করে
======== ======== ======== ======== ========
| Data | | Data | | Data | | Data | | Data |
| | -> | | -> | | -> | | -> | |
| P1 | | P2 | | P3 | | P4 | | P5 |
======== ======== ======== ======== ========
P(X) stands for Pointer to next node.
মনে রাখবেন যে আমি প্রতিটি "নোড" এর নিজস্ব ব্লকে তৈরি করেছি। এটি কারণ এগুলি মেমরির সংলগ্ন (এবং সম্ভবত সম্ভবত তা হবে না) এর গ্যারান্টিযুক্ত নয়।
আমি যদি পি 3 অ্যাক্সেস করতে চাই তবে আমি সরাসরি এটি অ্যাক্সেস করতে পারি না, কারণ আমি জানি না এটি স্মৃতিতে কোথায় রয়েছে। আমি জানি যে মূলটি (পি 1) কোথায়, সুতরাং পরিবর্তে আমাকে পি 1 থেকে শুরু করতে হবে এবং প্রতিটি পয়েন্টারকে পছন্দসই নোডে অনুসরণ করতে হবে।
এটি একটি ও (এন) চেহারা আপ সময় (প্রতিটি উপাদান যুক্ত হওয়ার সাথে সাথে চেহারা ব্যয় বৃদ্ধি পায়)। পি 4 এ পাওয়ার তুলনায় P1000 এ পাওয়া অনেক বেশি ব্যয়বহুল।
উচ্চ স্তরের ডেটা স্ট্রাকচার যেমন হ্যাশটবেলস, স্ট্যাকস এবং সারিগুলি সমস্ত অভ্যন্তরীণভাবে একটি অ্যারে (বা একাধিক অ্যারে) ব্যবহার করতে পারে তবে লিঙ্কযুক্ত তালিকাগুলি এবং বাইনারি গাছগুলি সাধারণত নোড এবং পয়েন্টার ব্যবহার করে।
আপনি ভাবতে পারেন যে কেন কেউ এমন একটি ডেটা স্ট্রাকচার ব্যবহার করবেন যাতে কেবল অ্যারে ব্যবহার না করে মান সন্ধান করার জন্য লিনিয়ার ট্র্যাভার্সাল প্রয়োজন হয়, তবে তাদের ব্যবহার রয়েছে have
আমাদের অ্যারে আবার নিন। এবার আমি অ্যারে এলিমেন্টটি খুঁজতে চাই যা '5' এর মান রাখে।
=====================================
| 6 | 4 | 2 | 3 | 1 | 5 |
=====================================
^ ^ ^ ^ ^ FOUND!
এই পরিস্থিতিতে, আমি এটির জন্য পয়েন্টারে কী যুক্ত করতে অফসেট জানি না, তাই আমাকে 0 থেকে শুরু করতে হবে এবং এটি না পাওয়া পর্যন্ত আমার পথে কাজ করতে হবে। এর অর্থ আমাকে 6 টি চেক করতে হবে।
এ কারণে, একটি অ্যারেতে মান সন্ধান করা ও (এন) হিসাবে বিবেচিত হয়। অ্যারে বড় হওয়ার সাথে সাথে অনুসন্ধানের ব্যয়ও বেড়ে যায়।
উপরের কথাটি মনে রাখবেন যেখানে আমি বলেছিলাম যে কখনও কখনও একটি অনুক্রমিক ডেটা কাঠামো ব্যবহারের সুবিধা থাকতে পারে? ডেটা অনুসন্ধান করা এই সুবিধাগুলির মধ্যে একটি এবং সর্বোত্তম উদাহরণগুলির মধ্যে একটি হ'ল বাইনারি ট্রি।
বাইনারি ট্রি হ'ল লিঙ্কযুক্ত তালিকার মতো একটি ডেটা স্ট্রাকচার, তবে একক নোডের সাথে সংযোগ স্থাপনের পরিবর্তে প্রতিটি নোড দুটি শিশু নোডের সাথে লিঙ্ক করতে পারে।
==========
| Root |
==========
/ \
========= =========
| Child | | Child |
========= =========
/ \
========= =========
| Child | | Child |
========= =========
Assume that each connector is really a Pointer
বাইনারি গাছে ডেটা সন্নিবেশ করা হলে, নতুন নোডটি কোথায় রাখবেন তা সিদ্ধান্ত নিতে এটি বেশ কয়েকটি নিয়ম ব্যবহার করে। মূল ধারণাটি হ'ল যদি নতুন মানটি পিতামাতার চেয়ে বেশি হয় তবে এটি এটি বামে সন্নিবেশ করায়, যদি এটি কম হয় তবে এটি ডানদিকে সন্নিবেশ করে।
এর অর্থ একটি বাইনারি গাছের মানগুলি দেখতে দেখতে পারে:
==========
| 100 |
==========
/ \
========= =========
| 200 | | 50 |
========= =========
/ \
========= =========
| 75 | | 25 |
========= =========
75 টি মানের জন্য বাইনারি গাছ অনুসন্ধান করার সময়, এই কাঠামোর কারণে আমাদের কেবলমাত্র 3 টি নোড (ও (লগ এন)) পরিদর্শন করতে হবে:
- 75 এর চেয়ে কম 100? রাইট নোডের দিকে তাকান
- 75 এর চেয়ে বেশি 50? বাম নোড তাকান
- 75 আছে!
আমাদের গাছে 5 টি নোড থাকা সত্ত্বেও, আমাদের বাকি দুটিটি দেখার দরকার নেই, কারণ আমরা জানতাম যে তারা (এবং তাদের সন্তানরা) সম্ভবত আমরা যে মূল্যটি খুঁজছিলাম তা ধারণ করতে পারে না। এটি আমাদের সন্ধানের সময় দেয় যা সবচেয়ে খারাপ অবস্থায় মানে আমাদের প্রতিটি নোডে যেতে হয়, তবে সর্বোত্তম ক্ষেত্রে আমাদের কেবল নোডের একটি ছোট্ট অংশটি দেখতে হয়।
সেই স্থানে অ্যারেগুলি পরাজিত হয়, ও (1) অ্যাক্সেসের সময় সত্ত্বেও তারা লিনিয়ার হে (এন) অনুসন্ধানের সময় সরবরাহ করে।
এটি মেমরির ডেটা স্ট্রাকচারের উপর অবিশ্বাস্যভাবে উচ্চ স্তরের ওভারভিউ যা অনেকগুলি বিবরণ এড়িয়ে যায়, তবে আশা করি এটি অন্যান্য ডেটা স্ট্রাকচারের তুলনায় অ্যারের শক্তি এবং দুর্বলতা চিত্রিত করে।