Follow Us
মাধ্যম নির্বাচন করুন / Select Medium:
Eng (English) Beng (বাংলা) Hindi (हिन्दी)
পশ্চিমবঙ্গ মধ্যশিক্ষা পর্ষদ (WBBSE) • শ্রেণি XI • Computer Science • অধ্যায় 4
আনুমানিক সময়: ৪৫ মিনিট
অগ্রগতি: অধ্যয়নে সক্রিয়

ডেটা স্ট্রাকচার

ডেটা স্ট্রাকচার হলো কম্পিউটার সায়েন্স ও সফটওয়্যার ইঞ্জিনিয়ারিংয়ের সবচেয়ে গুরুত্বপূর্ণ ভিত্তিপ্রস্তর, যা কম্পিউটারের প্রধান মেমরিতে (RAM) ডেটা সুসংগঠিতভাবে সংরক্ষণ, দ্রুত অনুসন্ধান ও দক্ষতার সাথে পরিচালনা করার গাণিতিক ও যৌক্তিক পদ্ধতি প্রদান করে। যেখানে প্রিমিটিভ ডেটা টাইপ (যেমন int, float, char) একক ও বিচ্ছিন্ন মান সংরক্ষণ করে, সেখানে নন-প্রিমিটিভ ডেটা স্ট্রাকচার বাস্তব জীবনের জটিল সমস্যা সমাধানের জন্য একাধিক ডেটা উপাদানের সুশৃঙ্খল বিন্যাস তৈরি করে। পশ্চিমবঙ্গ উচ্চমাধ্যমিক শিক্ষা সংসদ (WBCHSE)-এর একাদশ শ্রেণির সিলেবাস অনুসারে এই অধ্যায়ে লিনিয়ার অবিচ্ছিন্ন অ্যারে (একমাত্রিক ও দ্বিমাত্রিক মেমরি ম্যাপিং এবং রো-মেজর ও কলাম-মেজর ফর্মুলা), সীমাবদ্ধ প্রান্তীয় ডেটা কাঠামো যেমন লাস্ট-ইন ফার্স্ট-আউট (LIFO) স্ট্যাক ও ফার্স্ট-ইন ফার্স্ট-আউট (FIFO) কিউ, বৃত্তাকার কিউ (Circular Queue), হিপ মেমরিতে পয়েন্টার-সংযুক্ত ডায়নামিক সিঙ্গলি লিঙ্কড লিস্ট এবং মৌলিক সার্চিং ও সর্টিং অ্যালগরিদমের অ্যাসিম্পটোটিক জটিলতা বিশ্লেষণ বিশদভাবে আলোচনা করা হয়েছে।

অধ্যায়টির গুরুত্ব

আধুনিক কম্পিউটিংয়ে প্রসেসরের গতি যতই বৃদ্ধি পাক না কেন, যদি ডেটা মেমরিতে সঠিকভাবে সাজানো না থাকে তবে অ্যালগরিদমের কার্যক্ষমতা মারাত্মকভাবে হ্রাস পায়। একটি অনুপযুক্ত ডেটা কাঠামোর নির্বাচন মিলি-সেকেন্ডের কাজকে ঘণ্টার পর ঘণ্টা বিলম্বিত করতে পারে। অপারেটিং সিস্টেমের রিকার্সিভ ফাংশন কল ও সিস্টেম কল ট্র্যাক করতে স্ট্যাক (কল স্ট্যাক) অপরিহার্য; প্রিন্টার স্পুলিং এবং সিপিইউ প্রসেস শিডিউলিংয়ে কিউ ব্যবহৃত হয়; পরিবর্তনশীল মেমরি ব্যবস্থাপনায় লিঙ্কড লিস্ট ব্যবহৃত হয়; এবং কম্পিউটার গ্রাফিক্স ও ডাটাবেস সিস্টেমে বহুমাত্রিক অ্যারে ব্যবহৃত হয়। একাদশ শ্রেণির শিক্ষার্থীদের জন্য উচ্চমাধ্যমিক পরীক্ষায় সর্বোচ্চ নম্বর অর্জন এবং ভবিষ্যতে সফটওয়্যার ডেভেলপমেন্ট ও প্রতিযোগিতামূলক প্রোগ্রামিংয়ে সফল হতে ডেটা স্ট্রাকচারের তাত্ত্বিক ও ব্যবহারিক জ্ঞান অর্জন অপরিহার্য।

অধ্যায়ের বিষয়সূচি ও রূপরেখা

1 মডিউল ১: ডেটা স্ট্রাকচারের শ্রেণিবি...
2 মডিউল ২: অ্যারে: একমাত্রিক ও দ্বিমা...
3 মডিউল ৩: স্ট্যাক আর্কিটেকচার: LIFO...
4 মডিউল ৪: কিউ আর্কিটেকচার: FIFO মডেল...
5 মডিউল ৫: লিঙ্কড লিস্ট: ডায়নামিক মে...
6 মডিউল ৬: সার্চিং, সর্টিং ও ডেটা স্ট...

সম্পূর্ণ তত্ত্ব ও ধারণাগত আলোচনা

মডিউল ১: ডেটা স্ট্রাকচারের শ্রেণিবিন্যাস ও অ্যালগরিদমিক জটিলতা

১.১ ডেটা স্ট্রাকচারের সংজ্ঞা ও প্রয়োজনীয়তা

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

সঠিক ডেটা স্ট্রাকচার নির্বাচনের তিনটি প্রধান শর্ত: (১) ডেটার পরিমাণ ও তাদের অভ্যন্তরীণ সম্পর্ক, (২) মৌলিক অপারেশনগুলোর পুনরাবৃত্তির হার (যেমন অনুসন্ধান, সন্নিবেশ, মোচন), এবং (৩) সিস্টেম রিসোর্সের সীমাবদ্ধতা (সিপিইউ সময় ও মেমরির ব্যবহার)।

১.২ সামগ্রিক শ্রেণিবিন্যাস: প্রিমিটিভ বনাম নন-প্রিমিটিভ

ডেটা স্ট্রাকচারকে মূলত দুটি স্তরে বিভক্ত করা হয়:

  • প্রিমিটিভ ডেটা স্ট্রাকচার: যেসব মৌলিক ডেটা টাইপ সরাসরি কম্পিউটার হার্ডওয়্যার ও মেশিন নির্দেশনা দ্বারা সমর্থিত। যেমন C ভাষায় int, float, char, double এবং পয়েন্টার মেমরি অ্যাড্রেস। এরা প্রতিটি মুহূর্তে একটিমাত্র পরমাণবিক (atomic) মান ধারণ করে।
  • নন-প্রিমিটিভ ডেটা স্ট্রাকচার: একাধিক সমজাতীয় বা অসমজাতীয় ডেটা উপাদান সুসংগঠিত করার জন্য প্রিমিটিভ টাইপ থেকে উদ্ভূত জটিল কাঠামো। এগুলোকে আবার দুই ভাগে ভাগ করা হয়:
শ্রেণিবিভাগকাঠামোগত বৈশিষ্ট্যবাস্তব উদাহরণট্রাভার্সাল পদ্ধতি
লিনিয়ার ডেটা স্ট্রাকচারউপাদানগুলো একক অনুক্রমিক ধারায় সজ্জিত থাকে; প্রতিটি উপাদানের একটি নির্দিষ্ট পূর্বসূরি ও উত্তরসূরি থাকে।অ্যারে, স্ট্যাক, কিউ, লিঙ্কড লিস্টএকটিমাত্র রৈখিক পাসে সমস্ত উপাদান $O(n)$ সময়ে পরিদর্শন করা যায়।
নন-লিনিয়ার ডেটা স্ট্রাকচারউপাদানগুলো অনুক্রমিকভাবে না থেকে হায়ারারকিক্যাল বা বহু-শাখা নেটওয়ার্ক হিসেবে থাকে।ট্রি (বাইনারি ট্রি, BST), গ্রাফজটিল বহু-শাখা ট্রাভার্সাল (DFS, BFS, ইনঅর্ডার, প্রিঅর্ডার)।
স্ট্যাটিক ডেটা কাঠামোকম্পাইল টাইমে মেমরি নির্দিষ্ট হয়ে যায়; রানটাইমে মেমরির আকার ছোট বা বড় করা যায় না।স্থির আকারের অ্যারেস্ট্যাক বা ডেটা সেগমেন্টে মেমরি বরাদ্দ থাকে।
ডায়নামিক ডেটা কাঠামোপ্রোগ্রাম চলার সময় রানটাইমে হিপ মেমরি থেকে পয়েন্টার দ্বারা মেমরি যুক্ত ও মুক্ত করা যায়।লিঙ্কড লিস্ট, ডায়নামিক স্ট্যাক/ট্রিmalloc() ও free() দ্বারা প্রয়োজনমতো বাড়ে ও কমে।
১.৩ ডেটা স্ট্রাকচারের মৌলিক অপারেশনসমূহ

যেকোনো ডেটা স্ট্রাকচারের উপর প্রধান ছয়টি অপারেশন পরিচালিত হয়:

  1. ট্রাভার্সিং (Traversing): কাঠামোর প্রতিটি উপাদানকে অন্তত একবার পরিদর্শন ও প্রক্রিয়াকরণ করা (যেমন প্রিন্ট করা বা যোগফল নির্ণয়)।
  2. ইনসার্শন (Insertion): ডেটা স্ট্রাকচারের নির্দিষ্ট অবস্থানে একটি নতুন ডেটা উপাদান যুক্ত করা।
  3. ডিলিশন (Deletion): ডেটা স্ট্রাকচার থেকে কোনো বিদ্যমান উপাদান অপসারণ করা।
  4. সার্চিং (Searching): প্রদত্ত টার্গেট কি-এর মান অনুসারে কোনো উপাদানের উপস্থিতি বা মেমরি অবস্থান খুঁজে বের করা (লিনিয়ার ও বাইনারি সার্চ)।
  5. সর্টিং (Sorting): উপাদানগুলোকে কোনো নির্দিষ্ট যৌক্তিক ক্রমে (ঊর্ধ্বক্রম বা নিম্নক্রম) সাজানো (বাবল, সিলেকশন, ইনসার্শন সর্ট)।
  6. মার্জিং (Merging): দুটি ভিন্ন সাজানো ডেটা তালিকাকে একত্রিত করে একটি একক সাজানো তালিকা তৈরি করা।
টাইম কমপ্লেক্সিটি সতর্কতা: অ্যালগরিদমের কার্যক্ষমতা বিগ-ও (Big-O) দ্বারা পরিমাপ করা হয়: $O(1)$ হলো কনস্ট্যান্ট টাইম, $O(\log n)$ হলো লগারিদমিক টাইম, $O(n)$ হলো লিনিয়ার টাইম এবং $O(n^2)$ হলো কোয়াড্রেটিক টাইম।

মডিউল ২: অ্যারে: একমাত্রিক ও দ্বিমাত্রিক মেমরি ম্যাপিং

২.১ একমাত্রিক অ্যারে (1D Array) আর্কিটেকচার

একমাত্রিক অ্যারে হলো একই ডেটা টাইপের সমজাতীয় উপাদানের একটি নির্দিষ্ট আকারের অবিচ্ছিন্ন মেমরি ব্লক। C ভাষায় অ্যারের ইনডেক্স সর্বদা 0 থেকে শুরু হয়, অর্থাৎ $N$ আকারের একটি অ্যারের ইনডেক্স সীমা হলো $0, 1, 2, \dots, N-1$।

যেহেতু সমস্ত উপাদান মেমরিতে পাশাপাশি অবিচ্ছিন্নভাবে থাকে, তাই যেকোনো ইনডেক্স $A[i]$-এর মেমরি ঠিকানা মধ্যবর্তী উপাদান পরিদর্শন না করেই সরাসরি গাণিতিক সূত্রের মাধ্যমে $O(1)$ কনস্ট্যান্ট সময়ে বের করা সম্ভব।

২.২ 1D অ্যারে মেমরি অ্যাড্রেস গণনার সূত্র

যদি অ্যারে $A$-এর বেস অ্যাড্রেস $B$ (প্রথম উপাদানের মেমরি ঠিকানা), নিম্নসীমা $\text{LB}$ (C ভাষায় $\text{LB} = 0$) এবং প্রতিটি উপাদানের সাইজ $W$ বাইট হয়:

$$\text{Loc}(A[i]) = B + (i - \text{LB}) \times W$$

উদাহরণস্বরূপ, যদি int marks[50]-এর বেস অ্যাড্রেস $2000$ হয় এবং প্রতিটি ইন্টিজার $4$ বাইট ($W=4, \text{LB}=0$) গ্রহণ করে, তবে $marks[15]$-এর ঠিকানা হবে:

$$\text{Loc}(marks[15]) = 2000 + (15 - 0) \times 4 = 2000 + 60 = 2060$$

২.৩ C ভাষায় 1D অ্যারের মূল অ্যালগরিদম

অ্যালগরিদম ১: নির্দিষ্ট স্থানে উপাদান সন্নিবেশ (Insertion at Position $k$)

$N$ উপাদানবিশিষ্ট একটি অ্যারের $k$ ইনডেক্সে নতুন মান বসাতে হলে $N-1$ থেকে $k$ পর্যন্ত সমস্ত উপাদানকে এক ঘর ডানদিকে সরাতে (Shift right) হয়:

for (int i = N - 1; i >= k; i--) {
    A[i + 1] = A[i]; // ডানদিকে স্থানান্তর
}
A[k] = new_value;
N++; // মোট সংখ্যা বৃদ্ধি

টাইম কমপ্লেক্সিটি: বেস্ট কেস $O(1)$ (শেষে যোগ করলে), ওয়ার্স্ট কেস $O(n)$ (শুরুতে যোগ করলে সমস্ত উপাদান সরাতে হয়)।

অ্যালগরিদম ২: নির্দিষ্ট স্থান থেকে উপাদান মোচন (Deletion at Position $k$)

$k$ ইনডেক্সের উপাদান অপসারণ করতে হলে $k+1$ থেকে $N-1$ পর্যন্ত সমস্ত উপাদানকে এক ঘর বামদিকে সরাতে (Shift left) হয়:

for (int i = k; i < N - 1; i++) {
    A[i] = A[i + 1]; // বামদিকে স্থানান্তর
}
N--; // মোট সংখ্যা হ্রাস
২.৪ দ্বিমাত্রিক অ্যারে (2D Array) ও মেমরি রূপান্তর

দ্বিমাত্রিক অ্যারে হলো $M$ সারি (Rows) এবং $N$ কলামের (Columns) একটি ম্যাট্রিক্স, C ভাষায় যা int A[M][N] দ্বারা ঘোষিত হয়। কিন্তু কম্পিউটারের ফিজিক্যাল মেমরি (RAM) একমাত্রিক হওয়ায় কম্পাইলারকে দ্বিমাত্রিক গ্রিডকে রৈখিক ধারায় সাজাতে হয়। এর জন্য দুটি পদ্ধতি রয়েছে:

  1. রো-মেজর অর্ডার (Row-Major Order - RMO): মেমরিতে উপাদানগুলো সারি অনুসারে পরপর সংরক্ষিত হয়। প্রথমে সারি 0, তারপর সারি 1, তারপর সারি 2 সংরক্ষিত হয়। C, C++, Java এবং Python এই নিয়ম ব্যবহার করে।
  2. কলাম-মেজর অর্ডার (Column-Major Order - CMO): মেমরিতে উপাদানগুলো কলাম অনুসারে পরপর সংরক্ষিত হয়। প্রথমে কলাম 0, তারপর কলাম 1 সংরক্ষিত হয়। Fortran এবং MATLAB এই নিয়ম ব্যবহার করে।
পদ্ধতিমেমরি অ্যাড্রেস গণনার গাণিতিক সূত্রব্যাখ্যা
রো-মেজর অর্ডার (RMO)$$\text{Loc}(A[i][j]) = B + [(i - \text{LB}_r) \times N + (j - \text{LB}_c)] \times W$$$(i - \text{LB}_r)$ সংখ্যক সম্পূর্ণ সারি (প্রতিটিতে $N$ কলাম) পার করতে হয়, প্লাস চলতি সারির $j$ কলাম।
কলাম-মেজর অর্ডার (CMO)$$\text{Loc}(A[i][j]) = B + [(j - \text{LB}_c) \times M + (i - \text{LB}_r)] \times W$$$(j - \text{LB}_c)$ সংখ্যক সম্পূর্ণ কলাম (প্রতিটিতে $M$ সারি) পার করতে হয়, প্লাস চলতি কলামের $i$ সারি।
স্পার্স ম্যাট্রিক্স (Sparse Matrix): যেসব ম্যাট্রিক্সে অধিকাংশ উপাদানের মান শূন্য (Zero), সেগুলোকে স্পার্স ম্যাট্রিক্স বলা হয়। সাধারণ 2D অ্যারেতে এগুলো সংরক্ষণ করলে প্রচুর মেমরি অপচয় হয়। তাই ট্রিপলেট অ্যারে (Triplet Array: Row, Column, Value) ব্যবহার করে শুধুমাত্র অশূন্য মানগুলো সংরক্ষণ করা হয়।

মডিউল ৩: স্ট্যাক আর্কিটেকচার: LIFO মডেল ও কল স্ট্যাক

৩.১ স্ট্যাকের মূল নীতি (LIFO মডেল)

স্ট্যাক হলো একটি রৈখিক ডেটা কাঠামো যা LIFO (Last-In, First-Out) বা লাস্ট-ইন ফার্স্ট-আউট নীতি মেনে চলে। স্ট্যাকের উপাদান সংযোজন ও বিয়োজন শুধুমাত্র একটি নির্দিষ্ট প্রান্ত দিয়ে ঘটে, যাকে TOP বলা হয়। বিপরীত প্রান্তটি আবদ্ধ থাকে এবং তাকে Base বলা হয়।

৩.২ স্ট্যাকের আদিম অপারেশনসমূহ ও সীমাবদ্ধতা

MAX আকারের একটি স্ট্যাকে TOP পয়েন্টার শীর্ষ উপাদানের অবস্থান নির্দেশ করে:

  • প্রাথমিক খালি অবস্থা: TOP = -1।
  • PUSH অপারেশন: স্ট্যাকের শীর্ষে নতুন উপাদান প্রবেশ করানো।
    শর্ত যাচাই: যদি TOP == MAX - 1 হয়, তবে নতুন মান প্রবেশ করানো যায় না; এই অবস্থাকে স্ট্যাক ওভারফ্লো (Stack Overflow) বলা হয়। অন্যথায় TOP-কে ১ বৃদ্ধি করে মান রাখা হয়: Stack[++TOP] = val;।
  • POP অপারেশন: স্ট্যাকের শীর্ষ থেকে বর্তমান উপাদান অপসারণ করা।
    শর্ত যাচাই: যদি TOP == -1 হয়, তবে স্ট্যাক থেকে কোনো উপাদান পাওয়া যায় না; একে স্ট্যাক আন্ডারফ্লো (Stack Underflow) বলা হয়। অন্যথায় মান ফেরত দিয়ে TOP-কে ১ কমানো হয়: val = Stack[TOP--];।
  • PEEK অপারেশন: উপাদান মুছে না ফেলে শীর্ষ মান পরিদর্শন করা।
  • isEmpty(): TOP == -1 হলে সত্য ফেরত দেয়।
  • isFull(): TOP == MAX - 1 হলে সত্য ফেরত দেয়।
৩.৩ C ভাষায় স্ট্যাকের সাধারণ রূপায়ন
#include <stdio.h>
#define MAX 5

int stack[MAX];
int top = -1;

void push(int val) {
    if (top == MAX - 1) {
        printf("Stack Overflow!\n");
        return;
    }
    stack[++top] = val;
}

int pop() {
    if (top == -1) {
        printf("Stack Underflow!\n");
        return -1;
    }
    return stack[top--];
}
৩.৪ স্ট্যাকের বাস্তব প্রয়োগসমূহ
  1. ফাংশন কল ও রানটাইম কল স্ট্যাক: যখন কোনো ফাংশন কল করা হয়, অপারেটিং সিস্টেম লোকাল ভেরিয়েবল ও রিটার্ন অ্যাড্রেস সংবলিত একটি অ্যাক্টিভেশন রেকর্ড স্ট্যাকে পুশ করে। রিকার্শনে বেস কেস না পৌঁছানো পর্যন্ত ফ্রেম পুশ হতে থাকে এবং ফেরার সময় পপ হয়।
  2. এক্সপ্রেশন রূপান্তর (ইনফিক্স, প্রিফিক্স, পোস্টফিক্স): ইনফিক্স রাশিমালার বন্ধনী দূর করে কম্পিউটার মূল্যায়নের উপযোগী পোস্টফিক্স (Reverse Polish Notation) রাশিতে রূপান্তর করতে অপারেটর স্ট্যাক ব্যবহৃত হয়।
  3. পোস্টফিক্স রাশিমালা মূল্যায়ন: অপারেন্ড স্ট্যাক ব্যবহার করে একক পাসে দ্রুত রাশিমালা গণনা করা হয়।
  4. বন্ধনী সামঞ্জস্য যাচাই (Parentheses Balancing): কম্পাইলার কোড যাচাই করার সময় খোলার বন্ধনী ((, {, [) দেখলে স্ট্যাকে পুশ করে এবং বন্ধ করার বন্ধনী পেলে পপ করে মেলায়।
  5. ব্যাকট্র্যাকিং অ্যালগরিদম: ব্রাউজারের Back বোতাম, টেক্সট এডিটরের Undo/Redo এবং মেজ ট্রাভার্সাল।

মডিউল ৪: কিউ আর্কিটেকচার: FIFO মডেল ও বৃত্তাকার কিউ

৪.১ কিউ-এর মূল নীতি (FIFO মডেল)

কিউ হলো একটি রৈখিক ডেটা কাঠামো যা FIFO (First-In, First-Out) বা ফার্স্ট-ইন ফার্স্ট-আউট নীতিতে কাজ করে। কিউ-এর এক প্রান্ত দিয়ে উপাদান প্রবেশ করানো হয় যাকে REAR বলা হয়, এবং অন্য প্রান্ত দিয়ে উপাদান বের করা হয় যাকে FRONT বলা হয়।

৪.২ লিনিয়ার কিউ ও 'ফলস ওভারফ্লো' সমস্যা

একটি সাধারণ লিনিয়ার অ্যারে কিউতে উপাদান যুক্ত করার সাথে সাথে REAR বাড়তে বাড়তে একসময় MAX - 1-এ পৌঁছায়। এরপর কিছু উপাদান DEQUEUE করে বের করে দিলেও শুরুর দিকের ইনডেক্স ($0, 1, 2, \dots$) খালি হয়ে থাকা সত্ত্বেও লিনিয়ার কিউতে আর কোনো উপাদান ENQUEUE করা যায় না কারণ REAR ইতিমধ্যে শেষ সীমায় অবস্থান করছে। একে ফলস ওভারফ্লো (False Overflow) বলা হয়।

৪.৩ বৃত্তাকার কিউ (Circular Queue বা Ring Buffer) সমাধান

ফলস ওভারফ্লো দূর করার জন্য অ্যারেকে একটি বৃত্তাকার রিং হিসেবে কল্পনা করা হয়, যেখানে শেষ ইনডেক্স MAX - 1-এর পরের ইনডেক্স হিসেবে 0 ব্যবহৃত হয় মডিউলো পাটিগণিতের (%) মাধ্যমে।

বৃত্তাকার কিউ অবস্থামডিউলো সূত্রব্যাখ্যা
পয়েন্টার বৃদ্ধিindex = (index + 1) % MAXপয়েন্টার এক ঘর এগিয়ে যায়; শেষ সীমায় থাকলে শূন্যতে ফিরে আসে।
কিউ খালি অবস্থাFRONT == -1কিউতে বর্তমানে কোনো উপাদান নেই।
কিউ পূর্ণ অবস্থা(REAR + 1) % MAX == FRONTREAR এক ঘর এগোলে FRONT-এর সাথে ধাক্কা খাবে।
একক উপাদান নিষ্কাশনFRONT == REAR হলে FRONT = REAR = -1শেষ উপাদানটি বের হয়ে গেলে কিউ আবার খালি হয়ে যায়।
৪.৪ C ভাষায় বৃত্তাকার কিউ-এর কোড
#define MAX 5
int cqueue[MAX];
int front = -1, rear = -1;

void enqueue(int val) {
    if ((rear + 1) % MAX == front) {
        printf("Circular Queue Overflow!\n");
        return;
    }
    if (front == -1) front = 0;
    rear = (rear + 1) % MAX;
    cqueue[rear] = val;
}

int dequeue() {
    if (front == -1) {
        printf("Circular Queue Underflow!\n");
        return -1;
    }
    int val = cqueue[front];
    if (front == rear) front = rear = -1;
    else front = (front + 1) % MAX;
    return val;
}
৪.৫ কিউ-এর অন্যান্য রূপভেদ ও প্রয়োগ
  • ডবল এন্ডেড কিউ (Deque): FRONT ও REAR উভয় প্রান্ত দিয়েই উপাদান সন্নিবেশ ও মোচন করা সম্ভব।
  • প্রায়োরিটি কিউ (Priority Queue): উপাদানগুলোর একটি অগ্রাধিকার মান থাকে। সবচেয়ে বেশি অগ্রাধিকারপ্রাপ্ত উপাদান সবার আগে নিষ্কাশিত হয়।
  • বাস্তব প্রয়োগ: অপারেটিং সিস্টেমের রাউন্ড-রবিন সিপিইউ শিডিউলিং, প্রিন্টারের স্পুলিং বাফার, কিবোর্ড ইনপুট বাফার এবং গ্রাফের BFS ট্রাভার্সাল।

মডিউল ৫: লিঙ্কড লিস্ট: ডায়নামিক মেমরি ও সেলফ-রেফারেন্সিয়াল নোড

৫.১ অ্যারের সীমাবদ্ধতা ও লিঙ্কড লিস্টের উদ্ভব

অ্যারেতে সরাসরি অ্যাক্সেস সুবিধা থাকলেও বাস্তব ক্ষেত্রে এর প্রধান তিনটি অসুবিধা রয়েছে:

  • স্থির আকার: কম্পাইল টাইমে নির্ধারিত আকার পরে বাড়ানো বা কমানো যায় না।
  • অবিচ্ছিন্ন মেমরির বাধ্যবাধকতা: মেমরিতে মোট পর্যাপ্ত খালি স্থান থাকলেও তা যদি খণ্ড খণ্ডভাবে থাকে, তবে বড় অ্যারে তৈরি করা অসম্ভব।
  • ব্যয়বহুল সন্নিবেশ ও মোচন: শুরুতে বা মাঝে কোনো উপাদান যুক্ত বা মুছতে হলে বাকি উপাদানগুলোকে স্থানান্তর করতে হয়, যা অত্যন্ত ধীরগতির ($O(n)$ সময় নেয়)।
৫.২ সিঙ্গলি লিঙ্কড লিস্ট ও C স্ট্রাকচার

সিঙ্গলি লিঙ্কড লিস্ট হলো হিপ মেমরিতে গতিশীলভাবে তৈরি স্বাধীন নোড (Node)-এর একটি শৃঙ্খল। প্রতিটি নোডে দুটি অংশ থাকে:

  1. ডেটা অংশ (Data): প্রকৃত তথ্য বা উপাত্ত ধারণ করে।
  2. পয়েন্টার অংশ (Next): পরবর্তী নোডের মেমরি ঠিকানা ধারণ করে।
struct Node {
    int data;              // ডেটা মান
    struct Node *next;     // পরবর্তী নোডের পয়েন্টার
};
struct Node *head = NULL;  // তালিকার প্রথম নোডকে নির্দেশ করে
৫.৩ লিঙ্কড লিস্টের মূল অপারেশনসমূহ

১. ট্রাভার্সাল (Traversal): head থেকে শুরু করে শেষ নোডের NULL পর্যন্ত প্রতিটি নোড পরিদর্শন করা ($O(n)$ সময়)।

২. শুরুতে নতুন নোড যুক্ত করা (Insertion at Beginning - $O(1)$):

void insertAtBeginning(struct Node **head_ref, int val) {
    struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
    new_node->data = val;
    new_node->next = *head_ref; // আগের প্রথম নোডকে লিংক করা
    *head_ref = new_node;       // head পয়েন্টার আপডেট করা
}

৩. শুরুর নোড অপসারণ (Deletion of First Node - $O(1)$):

void deleteFromBeginning(struct Node **head_ref) {
    if (*head_ref == NULL) return;
    struct Node *temp = *head_ref;
    *head_ref = (*head_ref)->next;
    free(temp); // মেমরি লিক এড়াতে মুক্ত করা হলো
}
মেমরি সতর্কতা: malloc() দিয়ে নেওয়া মেমরি কাজ শেষে অবশ্যই free() করতে হবে, অন্যথায় মেমরি লিক (Memory Leak) ঘটে। আর মেমরি free করার পর সেই পয়েন্টার ব্যবহার করলে ড্যাংলিং পয়েন্টার (Dangling Pointer) ক্র্যাশ ঘটে।

মডিউল ৬: সার্চিং, সর্টিং ও ডেটা স্ট্রাকচারের তুলনামূলক বিশ্লেষণ

৬.১ সার্চিং অ্যালগরিদম: লিনিয়ার বনাম বাইনারি সার্চ
  • লিনিয়ার সার্চ (Linear Search): তালিকার প্রথম উপাদান থেকে শেষ উপাদান পর্যন্ত একের পর এক ক্রমিকভাবে টার্গেটের সাথে তুলনা করা হয়। এলোমেলো ও সাজানো উভয় অ্যারেতেই কাজ করে। টাইম কমপ্লেক্সিটি: বেস্ট $O(1)$, ওয়ার্স্ট $O(n)$।
  • বাইনারি সার্চ (Binary Search): ডিভাইড অ্যান্ড কনকার নীতিতে কাজ করে। মাঝের উপাদান mid-এর সাথে তুলনা করে প্রতি ধাপে অনুসন্ধান পরিসীমা অর্ধেক করে ফেলে। শর্ত: অ্যারে অবশ্যই সাজানো (Sorted) হতে হবে। টাইম কমপ্লেক্সিটি: বেস্ট $O(1)$, ওয়ার্স্ট $O(\log_2 n)$। ১০ লক্ষ ডেটায় লিনিয়ার সার্চে ১০ লক্ষ তুলনা লাগলেও বাইনারি সার্চে মাত্র ২০টি তুলনা লাগে!
৬.২ মৌলিক সর্টিং অ্যালগরিদম
  1. বাবল সর্ট (Bubble Sort): পাশাপাশি দুটি উপাদান তুলনা করে ভুল ক্রমে থাকলে সোয়াপ (Swap) করে। প্রতি পাসে সবচেয়ে বড় উপাদানটি শেষে চলে যায়। ফ্ল্যাগ ভেরিয়েবল ব্যবহার করলে সাজানো ডেটায় বেস্ট কেস $O(n)$ হয়, নতুবা $O(n^2)$।
  2. সিলেকশন সর্ট (Selection Sort): প্রতি পাসে অসাজানো অংশ থেকে ক্ষুদ্রতম উপাদানটি খুঁজে বের করে সেই অংশের শুরুতে সোয়াপ করে। এতে সর্বদা সর্বনিম্ন সংখ্যক সোয়াপ (সর্বোচ্চ $N-1$ টি বা $O(n)$) ঘটে। সকল ক্ষেত্রে টাইম কমপ্লেক্সিটি $O(n^2)$।
  3. ইনসার্শন সর্ট (Insertion Sort): তাসের মতো প্রতিটি নতুন উপাদানকে ইতিমধ্যে সাজানো অংশের সঠিক স্থানে ইনসার্ট করে। প্রায় সাজানো ডেটায় অত্যন্ত দ্রুত কাজ করে ($O(n)$ বেস্ট কেস)।
৬.৩ সামগ্রিক কমপ্লেক্সিটি তুলনা সারণী
ডেটা স্ট্রাকচার / অ্যালগরিদমঅ্যাক্সেসঅনুসন্ধানশুরুতে সংযোজনশুরুতে মোচনঅতিরিক্ত মেমরি
অ্যারে$O(1)$$O(n)$ / $O(\log n)$$O(n)$ (স্থানান্তর)$O(n)$ (স্থানান্তর)$O(1)$
লিঙ্কড লিস্ট$O(n)$$O(n)$$O(1)$$O(1)$নোড প্রতি পয়েন্টার
স্ট্যাক$O(n)$$O(n)$$O(1)$ (PUSH)$O(1)$ (POP)$O(1)$
বৃত্তাকার কিউ$O(n)$$O(n)$$O(1)$ (ENQUEUE)$O(1)$ (DEQUEUE)$O(1)$

প্রোগ্রামিং সিনট্যাক্স, কমান্ড ও অনুবাদক নীতি

1D অ্যারের উপাদান মেমরি অ্যাড্রেস গণনার সূত্র
$$\text{Loc}(A[i]) = B + (i - \text{LB}) \times W$$
2D অ্যারে রো-মেজর অর্ডার (RMO) সূত্র
$$\text{Loc}(A[i][j]) = B + [(i - \text{LB}_r) \times N + (j - \text{LB}_c)] \times W$$
2D অ্যারে কলাম-মেজর অর্ডার (CMO) সূত্র
$$\text{Loc}(A[i][j]) = B + [(j - \text{LB}_c) \times M + (i - \text{LB}_r)] \times W$$
স্ট্যাকের সীমানা শর্তসমূহ (LIFO ইনভেরিয়েন্ট)
$$\text{Overflow: } \text{TOP} = \text{MAX} - 1, \quad \text{Underflow: } \text{TOP} = -1$$
বৃত্তাকার কিউ মডিউলো রিং সূত্র
পরবর্তী স্লট = (Index + 1) ±od{MAX}, Full: ((REAR + 1) ±od{MAX}) = FRONT
বাইনারি সার্চ রিকারেন্স ও টাইম কমপ্লেক্সিটি
$$T(n) = T(n/2) + O(1) \implies O(\log_2 n)$$

সমাধানকৃত উদাহরণ ও প্রয়োগ (Solved Examples)

উদাহরণ 1
ধাপে ধাপে সমাধান / উত্তর:
ক-অংশ: 1D অ্যারের মেমরি ঠিকানা গণনা
প্রদত্ত মান:
• বেস অ্যাড্রেস $B = 1500$
• নিম্নসীমা $\text{LB} = 0$, লক্ষ্য ইনডেক্স $i = 18$
• উপাদানের আকার $W = 4$ বাইট

1D সূত্র প্রয়োগ করে:
$$\text{Loc}(A[i]) = B + (i - \text{LB}) \times W$$
$$\text{Loc}(A[18]) = 1500 + (18 - 0) \times 4 = 1500 + 72 = \mathbf{1572}$$

খ-অংশ: 2D ম্যাট্রিক্সের মেমরি ঠিকানা গণনা
প্রদত্ত মান:
• বেস অ্যাড্রেস $B = 4000$
• সারি সংখ্যা: $M = 10$ (সারি $1 \dots 10$, সুতরাং $\text{LB}_r = 1$)
• কলাম সংখ্যা: $N = 15$ (কলাম $1 \dots 15$, সুতরাং $\text{LB}_c = 1$)
• লক্ষ্য ইনডেক্স: $i = 6, j = 8$, উপাদানের আকার $W = 4$ বাইট

(১) রো-মেজর অর্ডার (RMO) সূত্র:
$$\text{Loc}(\text{MAT}[i][j]) = B + [(i - \text{LB}_r) \times N + (j - \text{LB}_c)] \times W$$
মান বসিয়ে পাই:
$$\text{Loc}(\text{MAT}[6][8]) = 4000 + [(6 - 1) \times 15 + (8 - 1)] \times 4$$
$$= 4000 + [5 \times 15 + 7] \times 4 = 4000 + [75 + 7] \times 4 = 4000 + 82 \times 4 = 4000 + 328 = \mathbf{4328}$$

(২) কলাম-মেজর অর্ডার (CMO) সূত্র:
$$\text{Loc}(\text{MAT}[i][j]) = B + [(j - \text{LB}_c) \times M + (i - \text{LB}_r)] \times W$$
মান বসিয়ে পাই:
$$\text{Loc}(\text{MAT}[6][8]) = 4000 + [(8 - 1) \times 10 + (6 - 1)] \times 4$$
$$= 4000 + [7 \times 10 + 5] \times 4 = 4000 + [70 + 5] \times 4 = 4000 + 75 \times 4 = 4000 + 300 = \mathbf{4300}$$
উত্তর: RMO-তে ঠিকানা হলো 4328 এবং CMO-তে ঠিকানা হলো 4300।
উদাহরণ 2
ধাপে ধাপে সমাধান / উত্তর:
অগ্রাধিকারের নিয়ম: ^ (সর্বোচ্চ ৩) > *, / (২) > +, - (১)।

ধাপস্ক্যান করা প্রতীকস্ট্যাকের অবস্থাআউটপুট স্ট্রিংপ্রযুক্ত নিয়ম
১((খোলার বন্ধনী স্ট্যাকে পুশ
২A(Aঅপারেন্ড সরাসরি আউটপুটে প্রেরণ
৩+( +Aঅপারেটর স্ট্যাকে পুশ
৪B( +A Bঅপারেন্ড আউটপুটে যোগ
৫*( + *A B* এর অগ্রাধিকার + এর চেয়ে বেশি, পুশ
৬C( + *A B Cঅপারেন্ড আউটপুটে যোগ
৭)A B C * +) পাওয়া গেছে: ( না আসা পর্যন্ত সব পপ
৮//A B C * +অপারেটর খালি স্ট্যাকে পুশ
৯(/ (A B C * +খোলার বন্ধনী পুশ
১০D/ (A B C * + Dঅপারেন্ড আউটপুটে যোগ
১১-/ ( -A B C * + Dঅপারেটর স্ট্যাকে পুশ
১২E/ ( -A B C * + D Eঅপারেন্ড আউটপুটে যোগ
১৩^/ ( - ^A B C * + D E^ এর অগ্রাধিকার বেশি, পুশ
১৪F/ ( - ^A B C * + D E Fঅপারেন্ড আউটপুটে যোগ
১৫)/A B C * + D E F ^ -পপ ^ এবং -, ( বর্জন
১৬শেষ[খালি]A B C * + D E F ^ - /বাকি অপারেটর / পপ করা হলো

চূড়ান্ত পোস্টফিক্স রূপ: A B C * + D E F ^ - /
উদাহরণ 3
ধাপে ধাপে সমাধান / উত্তর:
মূল্যায়ন পদ্ধতি: সংখ্যা পেলে স্ট্যাকে পুশ; অপারেটর পেলে শীর্ষের দুটি সংখ্যা পপ করে গণনা করে ফলাফল পুশ করতে হবে।

টোকেনধরনপপ করা মান ($op_1, op_2$)গণনাস্ট্যাকের অবস্থা
12অপারেন্ড--[12]
4অপারেন্ড--[12, 4]
/অপারেটর$op_2=4, op_1=12$$12 / 4 = 3$[3]
5অপারেন্ড--[3, 5]
3অপারেন্ড--[3, 5, 3]
*অপারেটর$op_2=3, op_1=5$$5 \times 3 = 15$[3, 15]
+অপারেটর$op_2=15, op_1=3$$3 + 15 = 18$[18]
8অপারেন্ড--[18, 8]
2অপারেন্ড--[18, 8, 2]
/অপারেটর$op_2=2, op_1=8$$8 / 2 = 4$[18, 4]
-অপারেটর$op_2=4, op_1=18$$18 - 4 = 14$[14]

চূড়ান্ত ফলাফল: 14
উদাহরণ 4
ধাপে ধাপে সমাধান / উত্তর:
বৃত্তাকার কিউ রূপান্তর সারণী (MAX = 4):

ক্রমঅপারেশনFRONTREARঅ্যারে অবস্থা: [0], [1], [2], [3]ব্যাখ্যা
০শুরুতে-1-1[ - , - , - , - ]কিউ খালি।
১Enqueue(10)00[ 10 , - , - , - ]খালি কিউ: front=0, rear=(0+1)%4=0।
২Enqueue(20)01[ 10 , 20 , - , - ]rear = (0+1)%4 = 1।
৩Enqueue(30)02[ 10 , 20 , 30 , - ]rear = (1+1)%4 = 2।
৪Dequeue()12[ - , 20 , 30 , - ]10 বের হলো; front = (0+1)%4 = 1। ইনডেক্স 0 খালি।
৫Enqueue(40)13[ - , 20 , 30 , 40 ]rear = (2+1)%4 = 3।
৬Enqueue(50)10[ 50 , 20 , 30 , 40 ]rear ঘুরে এলো: (3+1)%4 = 0! খালি স্থান 0 ব্যবহৃত হলো। কিউ সম্পূর্ণ পূর্ণ।
৭Dequeue()20[ 50 , - , 30 , 40 ]20 বের হলো; front = (1+1)%4 = 2। ইনডেক্স 1 খালি।
৮Enqueue(60)21[ 50 , 60 , 30 , 40 ]rear = (0+1)%4 = 1। মান 60 ইনডেক্স 1 এ রাখা হলো।

উপসংহার: সাধারণ লিনিয়ার কিউতে ধাপ ৬-এ ফলস ওভারফ্লো হতো, কিন্তু বৃত্তাকার কিউতে মেমরি সফলভাবে পুনর্ব্যবহৃত হয়েছে।
উদাহরণ 5
ধাপে ধাপে সমাধান / উত্তর:
(ক) শুরুতে [5] নোড সংযোজন:
১. malloc দ্বারা মেমরি বরাদ্দ: struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
২. ডেটা স্থাপন: new_node->data = 5;
৩. লিঙ্ক স্থাপন: new_node->next = head; (নতুন নোড এখন [10]-কে পয়েন্ট করে)
৪. হেড আপডেট: head = new_node;
• বর্তমান তালিকা: HEAD -> [5 | *] -> [10 | *] -> [25 | *] -> [40 | NULL] (সময়: $O(1)$)

(খ) মান 25 বিশিষ্ট নোডটি মোচন:
১. দুটি পয়েন্টার curr এবং prev দিয়ে তালিকা অনুসন্ধান করে কাঙ্ক্ষিত নোড [25]-এ পৌঁছানো হয়।
২. পূর্ববর্তী নোডের পয়েন্টার পরবর্তী নোডে সংযুক্ত করা: prev->next = curr->next; ([10]-এর পয়েন্টার সরাসরি [40]-এ যুক্ত হয়)।
৩. মেমরি মুক্ত করা: free(curr); (মেমরি লিক রোধে)
• চূড়ান্ত তালিকা: HEAD -> [5 | *] -> [10 | *] -> [40 | NULL]।
উদাহরণ 6
ধাপে ধাপে সমাধান / উত্তর:
প্রাথমিক অ্যারে: [45, 12, 89, 34, 23], দৈর্ঘ্য $N = 5$।

(১) বাবল সর্ট ট্রেস:
• পাস ১: 45>12 (সোয়াপ ১) → [12, 45, 89, 34, 23]; 45<89 (সোয়াপ নেই); 89>34 (সোয়াপ ২) → [12, 45, 34, 89, 23]; 89>23 (সোয়াপ ৩) → [12, 45, 34, 23, 89]।
• পাস ২: 12<45 (সোয়াপ নেই); 45>34 (সোয়াপ ৪) → [12, 34, 45, 23, 89]; 45>23 (সোয়াপ ৫) → [12, 34, 23, 45, 89]।
• পাস ৩: 12<34 (সোয়াপ নেই); 34>23 (সোয়াপ ৬) → [12, 23, 34, 45, 89]।
• পাস ৪: কোনো সোয়াপ নেই → সমাপ্ত।
বাবল সর্টে মোট সোয়াপ সংখ্যা = ৬ টি।

(২) সিলেকশন সর্ট ট্রেস:
• পাস ১: [45, 12, 89, 34, 23]-এর ক্ষুদ্রতম 12। A[0](45) ও A[1](12) সোয়াপ → [12, 45, 89, 34, 23] (সোয়াপ ১)।
• পাস ২: বাকি অংশের ক্ষুদ্রতম 23। A[1](45) ও A[4](23) সোয়াপ → [12, 23, 89, 34, 45] (সোয়াপ ২)।
• পাস ৩: বাকি অংশের ক্ষুদ্রতম 34। A[2](89) ও A[3](34) সোয়াপ → [12, 23, 34, 89, 45] (সোয়াপ ৩)।
• পাস ৪: বাকি অংশের ক্ষুদ্রতম 45। A[3](89) ও A[4](45) সোয়াপ → [12, 23, 34, 45, 89] (সোয়াপ ৪)।
সিলেকশন সর্টে মোট সোয়াপ সংখ্যা = ৪ টি।

তুলনামূলক বিশ্লেষণ: উভয় পদ্ধতির টাইম কমপ্লেক্সিটি $O(n^2)$ হলেও সিলেকশন সর্টে সোয়াপ সংখ্যা সর্বদা কম (সর্বোচ্চ $N-1$), যা ফ্ল্যাশ মেমরি রাইটের ক্ষেত্রে অত্যন্ত উপযোগী।

সাধারণ ভুলত্রুটি ও সতর্কতা (Common Traps)

সাধারণ ভুল ধারণা

বৃত্তাকার কিউতে পূর্ণ অবস্থা যাচাইয়ের জন্য 'front == rear' ব্যবহার করা।

সঠিক পদ্ধতি ও সমাধান

বৃত্তাকার কিউতে 'front == rear' নির্দেশ করে যে কিউতে কেবল একটিমাত্র উপাদান অবশিষ্ট রয়েছে। সঠিক পূর্ণ শর্ত হলো '(rear + 1) % MAX == front'।

সাধারণ ভুল ধারণা

এলোমেলো বা অসাজানো (Unsorted) অ্যারেতে বাইনারি সার্চ চালানো।

সঠিক পদ্ধতি ও সমাধান

বাইনারি সার্চ কেবল সাজানো ডেটাতেই কাজ করে। অসাজানো অ্যারেতে চালালে এটি ভুল বা অবাস্তব ফলাফল দেবে। প্রথমে ডেটা সর্ট করতে হবে অথবা লিনিয়ার সার্চ ব্যবহার করতে হবে।

সাধারণ ভুল ধারণা

লিঙ্কড লিস্টে নোড যোগ করার সময় আগের সংযোগ বিচ্ছিন্ন করে ফেলা।

সঠিক পদ্ধতি ও সমাধান

নতুন নোড ঢোকানোর সময় সর্বদা আগে নতুন নোডের next-কে বর্তমান তালিকার সাথে লিংক করতে হবে ('new_node->next = head;'), তারপর 'head = new_node;' করতে হবে। উল্টো করলে মূল তালিকার সব নোড হারিয়ে যাবে।

সাধারণ ভুল ধারণা

C ভাষার মেমরি অ্যাড্রেস গণনায় রো-মেজরের পরিবর্তে কলাম-মেজরের সূত্র বসানো।

সঠিক পদ্ধতি ও সমাধান

C ভাষা সর্বদা রো-মেজর অর্ডার মেনে চলে, যাতে সারি ব্যবধানকে মোট কলাম সংখ্যা (N) দ্বারা গুণ করতে হয়: Base + [(i - LBr) * N + (j - LBc)] * W।

সাধারণ ভুল ধারণা

স্ট্যাক থেকে POP করার পূর্বে আন্ডারফ্লো (top == -1) চেক না করা।

সঠিক পদ্ধতি ও সমাধান

top == -1 থাকা অবস্থায় pop করলে Stack[-1] অ্যাক্সেস হয়ে মেমরি করাপশন বা সেগমেন্টেশন ফল্ট ঘটে। সর্বদা isEmpty() যাচাই করা আবশ্যক।

অধ্যায় সারসংক্ষেপ ও গুরুত্বপূর্ণ বিষয়

মূল বিষয় 1
ডেটা স্ট্রাকচার মেমরিতে ডেটা সুসংগঠিতভাবে সাজিয়ে অ্যালগরিদমের কার্যক্ষমতা বৃদ্ধি করে। লিনিয়ার ডেটা স্ট্রাকচার (অ্যারে, স্ট্যাক, কিউ, লিঙ্কড লিস্ট) অনুক্রমিক ধারায় ডেটা রাখে এবং নন-লিনিয়ার ডেটা কাঠামো (ট্রি, গ্রাফ) বহুমাত্রিক সম্পর্ক তৈরি করে। অ্যারে অবিচ্ছিন্ন মেমরি ম্যাপিংয়ের মাধ্যমে O(1) সরাসরি অ্যাক্সেস সুবিধা দেয়, যা C ভাষায় রো-মেজর অর্ডার মেনে চলে। স্ট্যাক LIFO নীতি মেনে রিকার্শন ও এক্সপ্রেশন মূল্যায়নে ব্যবহৃত হয়। কিউ FIFO নীতি মেনে চলে, যেখানে বৃত্তাকার কিউ মডিউলো পাটিগণিতের সাহায্যে ফলস ওভারফ্লো রোধ করে। সিঙ্গলি লিঙ্কড লিস্ট সেলফ-রেফারেন্সিয়াল নোডের মাধ্যমে ডায়নামিক মেমরি পরিচালনা করে। সার্চিংয়ের ক্ষেত্রে লিনিয়ার সার্চ (O(n)) ও বাইনারি সার্চ (O(log n)) এবং সর্টিংয়ের ক্ষেত্রে বাবল, সিলেকশন ও ইনসার্শন সর্ট গুরুত্বপূর্ণ।

স্ব-মূল্যায়ন অনুশীলন (Check Your Understanding)

মূল ধারণাগত স্পষ্টতা যাচাই করার জন্য অনুশীলন প্রশ্ন। উত্তর দেখার আগে নিজে সমাধান করার চেষ্টা করো।

1
অ্যারেকে স্ট্যাটিক এবং লিঙ্কড লিস্টকে ডায়নামিক ডেটা স্ট্রাকচার বলা হয় কেন? মেমরি বরাদ্দের ভিত্তিতে ব্যাখ্যা করো।
উত্তর ও ব্যাখ্যা দেখুন
উত্তর: অ্যারের মেমরি আকার কম্পাইল টাইমে নির্দিষ্টভাবে ঘোষণা করতে হয়। প্রোগ্রাম চলাকালীন রানটাইমে এর আকার বাড়ানো বা কমানো যায় না; প্রয়োজন শেষ হলেও অতিরিক্ত মেমরি আটকে থাকে। তাই অ্যারে স্ট্যাটিক। পক্ষান্তরে, লিঙ্কড লিস্টের ক্ষেত্রে কোনো নির্দিষ্ট আকার আগে থেকে বরাদ্দ করতে হয় না। রানটাইমে malloc() ব্যবহার করে প্রয়োজনমতো নতুন নোডের জন্য হিপ মেমরি নেওয়া হয় এবং কাজ শেষে free() দিয়ে তা তাৎক্ষণিক অবমুক্ত করা যায়। ফলে এটি কাজের চাহিদানুসারে বৃদ্ধি ও হ্রাস পায়, তাই লিঙ্কড লিস্ট ডায়নামিক।
2
লিনিয়ার কিউতে 'ফলস ওভারফ্লো' কী? বৃত্তাকার কিউ কীভাবে গাণিতিকভাবে এই সমস্যার সমাধান করে?
উত্তর ও ব্যাখ্যা দেখুন
উত্তর: লিনিয়ার কিউতে উপাদান প্রবেশ করাতে করাতে যখন REAR পয়েন্টার শেষ ইনডেক্স MAX - 1 এ পৌঁছায়, তখন পূর্বে কিছু উপাদান DEQUEUE করে বের করে দিলেও সামনের ইনডেক্সগুলো খালি থাকা সত্ত্বেও নতুন উপাদান প্রবেশ করানো যায় না এবং কিউ ওভারফ্লো দেখায়। একে ফলস ওভারফ্লো বলে। বৃত্তাকার কিউ মডিউলো পাটিগণিত ব্যবহার করে এই সমস্যার সমাধান করে: rear = (rear + 1) % MAX। ফলে rear যখন শেষ সীমায় পৌঁছায়, তখন (MAX - 1 + 1) % MAX = 0 হয়ে পয়েন্টারটি পুনরায় শূন্য ইনডেক্সে ঘুরে আসে এবং খালি স্থানগুলোকে সফলভাবে কাজে লাগায়।
3
ইনফিক্স, প্রিফিক্স ও পোস্টফিক্স রাশিমালার পার্থক্য কী? কম্পিউটারে মূল্যায়নের জন্য পোস্টফিক্স রাশিকে অগ্রাধিকার দেওয়া হয় কেন?
উত্তর ও ব্যাখ্যা দেখুন
উত্তর: ইনফিক্স রাশিতে অপারেটর অপারেন্ডের মাঝে থাকে (A + B)। প্রিফিক্সে অপারেটর অপারেন্ডের পূর্বে থাকে (+ A B)। পোস্টফিক্সে অপারেটর অপারেন্ডের পরে থাকে (A B +)। কম্পিউটারে পোস্টফিক্স রাশিকে অগ্রাধিকার দেওয়ার কারণ: (১) এটিতে কোনো বন্ধনীর প্রয়োজন হয় না, (২) মূল্যায়নের সময় কোনো অপারেটরের অগ্রাধিকার বা অ্যাসোসিয়েটিভিটির জটিল নিয়ম মনে রাখতে হয় না, এবং (৩) একটি একক অপারেন্ড স্ট্যাক ব্যবহার করে বাম থেকে ডানে মাত্র একবার স্ক্যান করে $O(n)$ সময়ে এর মান বের করা যায়।
4
বাবল সর্ট কোন শর্তে O(n) বেস্ট-কেস টাইম কমপ্লেক্সিটি অর্জন করে? অ্যালগরিদমে কী পরিবর্তন আনতে হয়?
উত্তর ও ব্যাখ্যা দেখুন
উত্তর: সাধারণ বাবল সর্টে নেস্টেড লুপের কারণে সর্বদা O(n^2) সময় লাগে। তবে একটি বুলিয়ান ফ্ল্যাগ ভেরিয়েবল (যেমন swapped = 0;) ব্যবহার করে যদি দেখা যায় যে প্রথম পাসে দুটি পাশাপাশি উপাদানের মধ্যে একটিও সোয়াপ করার প্রয়োজন হয়নি, তবে প্রমাণিত হয় যে প্রদত্ত অ্যারেটি ইতিমধ্যে সম্পূর্ণরূপে সাজানো রয়েছে। এই অবস্থায় অ্যালগরিদমটি সাথে সাথে ব্রেক করে থেমে যায়। ফলে প্রথম পাসে মাত্র n - 1 টি তুলনা করেই কাজ শেষ হয়ে যায় এবং O(n) লিনিয়ার টাইম কমপ্লেক্সিটি অর্জিত হয়।
5
C ভাষায় ডায়নামিক মেমরি ব্যবহারের প্রধান দুটি বিপদ কী কী? কীভাবে এগুলি প্রতিরোধ করা যায়?
উত্তর ও ব্যাখ্যা দেখুন
উত্তর: প্রধান দুটি বিপদ হলো: (১) মেমরি লিক (Memory Leak): malloc() দ্বারা বরাদ্দকৃত মেমরি free() না করে পয়েন্টার পরিবর্তন করলে সেই মেমরি চিরতরে আটকে থাকে। প্রতিকার: কাজ শেষ হওয়া মাত্র free(ptr) কল করা। (২) ড্যাংলিং পয়েন্টার (Dangling Pointer): মেমরি free() করার পরেও পয়েন্টারটি যদি সেই বাতিল ঠিকানাকে ধরে রাখে এবং পরবর্তীতে ডিরিফারেন্স করা হয়, তবে সিস্টেম ক্র্যাশ করতে পারে। প্রতিকার: মেমরি free() করার সাথে সাথে পয়েন্টারে NULL মান নির্ধারণ করা: free(ptr); ptr = NULL;।
অধ্যায় পড়া শেষ হয়েছে?
অনুশীলন শুরু করো

অনলাইন মক টেস্ট দিয়ে প্রস্তুতি যাচাই করো

পশ্চিমবঙ্গ মধ্যশিক্ষা পর্ষদ (WBBSE) পাঠ্যক্রম অনুযায়ী বহু বিকল্পীয় প্রশ্ন (MCQ) সমাধান করো। তাৎক্ষণিক ফলাফল, সঠিক ব্যাখ্যা এবং নিজের স্কোর জেনে নাও।