কেন আমরা অন্যান্য ডেটা স্ট্রাকচারের পরিবর্তে অ্যারে ব্যবহার করব?


195

আমি যখন প্রোগ্রামিং করছিলাম, আমি এমন কোনও উদাহরণ দেখিনি যেখানে একটি অ্যারে তথ্যের অন্য ফর্মের চেয়ে স্টোর করার জন্য ভাল। আমি প্রকৃতপক্ষে প্রোগ্রামিং ভাষাগুলিতে যুক্ত হওয়া "বৈশিষ্ট্যগুলি" এটির দ্বারা উন্নত হয়েছি এবং এটি তাদের প্রতিস্থাপন করেছে। আমি এখন দেখছি যে তারা প্রতিস্থাপন করা হয়নি, বরং নতুন জীবন দেওয়া হয়েছে, তাই বলার জন্য।

সুতরাং, মূলত, অ্যারে ব্যবহারের বিন্দুটি কী?

এটি এতটা নয় যে আমরা কম্পিউটারের দৃষ্টিকোণ থেকে অ্যারেগুলি ব্যবহার করি, তবে আমরা কেন প্রোগ্রামিং অবস্থান থেকে একটি অ্যারে ব্যবহার করব (একটি সূক্ষ্ম পার্থক্য)। অ্যারে দিয়ে কম্পিউটার কী করে তা প্রশ্নের মূল বিষয় ছিল না।


2
কম্পিউটার অ্যারে দিয়ে কী করে তা বিবেচনা করে দেখছেন না কেন? আমাদের কাছে একটি বাড়ির নম্বর ব্যবস্থা রয়েছে কারণ আমাদের রাস্তাগুলি স্ট্রাইট । এটা অ্যারে জন্য হয়।
lcn

আপনার " অন্যান্য ডেটা স্ট্রাকচার " বা " অন্য ফর্ম " বলতে কী বোঝায়? আর কী উদ্দেশ্যে?
তেভেমাদার

উত্তর:


771

একটি পাঠের জন্য সময় ফিরে যেতে। যদিও আমরা আজ আমাদের অভিনব পরিচালিত ভাষাগুলিতে এই বিষয়গুলি সম্পর্কে খুব বেশি ভাবি না, সেগুলি একই ভিত্তিতে নির্মিত, সুতরাং আসুন দেখে নেওয়া যাক সিটিতে মেমরি কীভাবে পরিচালিত হয় 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) অ্যাক্সেসের সময় সত্ত্বেও তারা লিনিয়ার হে (এন) অনুসন্ধানের সময় সরবরাহ করে।

এটি মেমরির ডেটা স্ট্রাকচারের উপর অবিশ্বাস্যভাবে উচ্চ স্তরের ওভারভিউ যা অনেকগুলি বিবরণ এড়িয়ে যায়, তবে আশা করি এটি অন্যান্য ডেটা স্ট্রাকচারের তুলনায় অ্যারের শক্তি এবং দুর্বলতা চিত্রিত করে।


1
@ জোনাথন: আপনি চিত্রটি 5 ম এলিমেন্টের দিকে নির্দেশ করার জন্য আপডেট করেছেন তবে আপনি মাইআরে [4] কে মাইআরাইতে পরিবর্তন করেছেন [5] সুতরাং এটি এখনও ভুল আছে, সূচকটি আবার 4 এ পরিবর্তন করুন এবং চিত্রটি যেমন আছে তেমন রাখুন এবং আপনার ভাল হওয়া উচিত ।
রবার্ট গাম্বল

54
এই "পোস্ট করা" সম্প্রদায়ের উইকি "সম্পর্কে পোস্টগুলি" যথাযথ "প্রতিনিধিত্বের জন্য মূল্যবান
Quibbleome

8
চমৎকার উত্তর. তবে আপনি যে গাছটি বর্ণনা করেছেন তা বাইনারি অনুসন্ধান গাছ - একটি বাইনারি গাছ কেবল এমন একটি গাছ যেখানে প্রতিটি নোডে সর্বাধিক দুটি শিশু থাকে। আপনার যে কোনও ক্রমে উপাদানগুলির সাথে বাইনারি গাছ থাকতে পারে। আপনার বর্ণনা অনুসারে বাইনারি অনুসন্ধান ট্রিটি সাজানো হয়েছে।
gnud

1
ভাল ব্যাখ্যা, তবে আমি নটপিক করতে সহায়তা করতে পারি না ... যদি আপনি আইটেমগুলিকে বাইনারি অনুসন্ধানের ট্রিগুলিতে পুনরায় অর্ডার করার অনুমতি দেওয়া হয় তবে আপনি অ্যারেতে থাকা উপাদানগুলিকে কেন পুনরায় সারণ করতে পারবেন না যাতে বাইনারি অনুসন্ধানও এতে কাজ করতে পারে? আপনি কোনও গাছের জন্য ও (এন) সন্নিবেশ / মোছার বিষয়ে আরও বিশদে যেতে পারেন তবে অ্যারের জন্য হে (এন)।
বাজারগুলি

2
বাইনারি গাছের উপস্থাপনাটি কি ও (লগ এন) নয় কারণ অ্যাক্সেসের সময় ডেটা সেটের আকারের সাথে সম্পর্কিত লোগারিথেমিকভাবে বৃদ্ধি পায়?
ইভান প্লেইস

73

ও (1) এলোমেলো অ্যাক্সেসের জন্য, যা মারতে পারে না।


6
কোন পয়েন্টে? ও (1) কী? এলোমেলো অ্যাক্সেস কি? এটাকে মারধর করা যাবে না কেন? আর একটা কথা?
জেসন

3
ও (1) এর অর্থ ধ্রুব সময়, উদাহরণস্বরূপ আপনি যদি কোনও অ্যারের এন-এসিম উপাদান পেতে চান তবে আপনি কেবল এটির সূচক (অ্যারে [এন-1]) এর মাধ্যমে সরাসরি অ্যাক্সেস করতে পারেন, উদাহরণস্বরূপ একটি লিঙ্কযুক্ত তালিকার সাথে, আপনার কাছে মাথাটি সন্ধান করতে এবং তারপরে পরবর্তী নোডে ধারাবাহিকভাবে n-1 বার যা ও (এন) হয়, লিনিয়ার সময়।
সিএমএস

8
বিগ-ও স্বরলিপি বর্ণনা করে যে কীভাবে কোনও ইনপুট আকারের ভিত্তিতে অ্যালগরিদমের গতি পরিবর্তিত হয়। একটি ও (এন) অ্যালগরিদম দ্বিগুণ আইটেমের সাথে দ্বিগুণ এবং আট বারের মতো অনেকগুলি আইটেমের সাথে চালাতে 8 বছরের বেশি সময় লাগবে। অন্য কথায় একটি ও (এন) অ্যালগরিদমের গতি [নিয়মিত ...] এর সাথে পরিবর্তিত হয়
গ্যারেথ

8
এর ইনপুট আকার। ও (1) বোঝায় যে ইনপুটটির আকার ('এন') অ্যালগরিদমের গতিতে ফ্যাক্টর করে না, ইনপুট আকার নির্বিশেষে এটি একটি ধ্রুবক গতি
গ্যারেথ

9
আমি আপনার ও (1) দেখতে পাচ্ছি এবং আপনাকে ও (0) বাড়িয়ে দেব।
ক্রিস কনওয়ে

23

সমস্ত প্রোগ্রাম একই জিনিস করে না বা একই হার্ডওয়্যারে চালিত হয় না।

বিভিন্ন ভাষার বৈশিষ্ট্য কেন বিদ্যমান তা এটিই সাধারণত উত্তর। অ্যারেগুলি একটি মূল কম্পিউটার বিজ্ঞান ধারণা। তালিকা / ম্যাট্রিক / ভেক্টর / যে কোনও উন্নত ডেটা কাঠামো মারাত্মকভাবে কার্য সম্পাদনকে প্রভাবিত করবে এবং বেশ কয়েকটি সিস্টেমে সম্পূর্ণরূপে অবর্ণনীয় হতে পারে তার সাথে অ্যারেগুলি প্রতিস্থাপন করা হবে। এমন অনেকগুলি কেস রয়েছে যেখানে এই "অ্যাডভান্সড" ডেটা সংগ্রহের অবজেক্টগুলির মধ্যে একটি ব্যবহার করা উচিত কারণ প্রশ্নে কর্মসূচি রয়েছে।

ব্যবসায়িক প্রোগ্রামিংয়ে (যা আমরা বেশিরভাগই করি), আমরা তুলনামূলকভাবে শক্তিশালী হার্ডওয়্যারকে লক্ষ্য করতে পারি। জাভাতে সি # বা ভেক্টরের একটি তালিকা ব্যবহার করা এই পরিস্থিতিতে করা সঠিক পছন্দ কারণ এই কাঠামোগত বিকাশকারীকে লক্ষ্যগুলি দ্রুত অর্জন করতে দেয়, যার ফলে এই ধরণের সফ্টওয়্যার আরও বৈশিষ্ট্যযুক্ত হতে পারে।

এমবেডেড সফ্টওয়্যার বা অপারেটিং সিস্টেম লেখার সময় একটি অ্যারে প্রায়শই ভাল পছন্দ হতে পারে। যখন একটি অ্যারে কম কার্যকারিতা সরবরাহ করে, এটি কম র‍্যাম নেয় এবং সংকলক কোডগুলিকে অ্যারেগুলিতে নজর রাখার জন্য কোডটিকে আরও দক্ষতার সাথে অপ্টিমাইজ করতে পারে।

আমি নিশ্চিত আমি এই কেসগুলির জন্য বেশ কয়েকটি সুবিধাদি ছেড়ে দিচ্ছি তবে আমি আশা করি আপনি পয়েন্টটি পেয়ে যাবেন।


4
হাস্যকরভাবে, জাভাতে আপনার ভেক্টরের পরিবর্তে একটি অ্যারেলিস্ট (বা একটি লিংকডলিস্ট) ব্যবহার করা উচিত। এটি কোনও ভেক্টর সিঙ্ক্রোনাইজ হওয়ার সাথে করা যা সাধারণত অপ্রয়োজনীয় ওভারহেড।
আশিরলে

0

অ্যারেগুলির সুবিধাগুলি দেখার জন্য একটি উপায় হ'ল অ্যারেগুলির ও (1) অ্যাক্সেসের ক্ষমতা প্রয়োজন এবং তাই এটি মূলধনযুক্ত:

  1. আপনার অ্যাপ্লিকেশনটির সন্ধানের টেবিলগুলিতে (নির্দিষ্ট শ্রেণিবদ্ধ প্রতিক্রিয়াগুলি অ্যাক্সেস করার জন্য একটি স্ট্যাটিক অ্যারে)

  2. স্মৃতিচারণ (ইতিমধ্যে গণিত জটিল ফাংশন ফলাফল, যাতে আপনি আবার ফাংশন মান গণনা না করে, লগ এক্স বলুন)

  3. চিত্র প্রক্রিয়াকরণের জন্য উচ্চ গতির কম্পিউটার ভিশন অ্যাপ্লিকেশনগুলির প্রয়োজন ( https://en.wikedia.org/wiki/Lookup_table#Lookup_tables_in_image_processing )

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.