৭-৩ঃ Insert at Head and Tail at Singly Linked List Recap

এবার আমরা পূর্বের আর্টিকেলে দেখা ইন্সারট ফাংশন এর সাথে হেড এবং টেলে ইন্সারট করাও দেখে নিব।

হেডে ইন্সারট করা খুবই ইজি। আমরা শুরুতে নতুন নোড ডিক্লেয়ার করে নিব। এখন এই নতুন নোডটিই আমাদের হেড নোড, তাই নতুন নোড এর শেষে পূর্বের হেড কে কানেক্ট করে দিব এবং এরপর হেড পয়েন্টারকে চেঞ্জ করে নতুন নোডে নিয়ে আসব।

void insert_head(Node *&head, int val)
{
    Node *newNode = new Node(val);  // শুরুতে নতুন নোড ডিক্লেয়ার করে নিব
    newNode->next = head;           // নতুন নোড এর শেষে পূর্বের হেড কে কানেক্ট করে দিব
    head = newNode;                 // হেড পয়েন্টারকে চেঞ্জ করে নতুন নোডে নিয়ে আসব।
}

এবার আমরা টেলে ইন্সারট করা দেখব। আমরা গত মডিউলে টেলে ইন্সারট করা দেখেছি। সেখানে আমরা শুরু থেকে শেষ পর্যন্ত লুপ চালাতাম তারপর টেলে ইন্সারট করতাম। এতে আমাদের টেলে ইন্সারট করার কম্পেক্সিটি হতো O(N)। এটিকে আমরা খুব ইজিলি O(1) এ নামিয়ে নিয়ে আসতে পারি। আমাদের যেরকম হেড পয়েন্টার ছিল, সেইমভাবে আমরা যদি টেল পয়েন্টার রাখি তাহলে আমাদের আর লুপ চালাতে হবে না। আমরা জাস্ট টেলের শেষে নতুন নোড কানেক্ট করে দিলেই হবে। কোন লুপ চালাতে হবে না। তাই এটির কমপ্লেক্সিটি হবে O(1)


void insert_tail(Node *&head, Node *&tail, int val)    // হেড টেল দুটিই নিচ্ছি আমরা কারন হেড টেল দুটোর মানই চেঞ্জ হতে পারে।                                                        
{
    Node *newNode = new Node(val);      // শুরুতে নতুন নোড ডিক্লেয়ার করে নিচ্ছি। 
    if (head == NULL)                // চেক করছি হেড নাল কিনা। 
    {
        head = newNode;            // হেড নাল থাকা মানে আমার লিঙ্কড লিস্ট এখন ফাঁকা। 
        tail = newNode;            // তাই নতুন নোডটিই এখন হেড এবং এটিই বর্তমানে টেল। 
        return;                    // কাজ শেষ তাই রিটার্ন করা হচ্ছে। 
    }
    tail->next = newNode;          // আর যদি হেড নালে না থাকে তাহলে আমরা টেলের শেষে নতুন নোডকে কানেক্ট করে দিচ্ছি। 
    tail = newNode;                // তারপর টেল পয়েন্টার কে নতুন নোডে নিয়ে আসছি। 
}

এই ইন্সারট টেল ফাংশনটির কমপ্লেক্সিটি O(1)

সম্পূর্ণ কোডঃ

Last updated