একটি বাইনারি ট্রি বিনামূল্যে


13

সুতরাং আপনি কিছু প্রাথমিক কম্পিউটার বিজ্ঞান ধারণা পড়ার আগে।

  1. একটি বাইনারি ট্রি একটি গতিশীল বরাদ্দ কাঠামো (সাধারণত অর্ডার করা স্টোরেজের জন্য ব্যবহৃত হয়)।
  2. বাইনারি গাছগুলির প্রকৃতির কারণ এটি সাধারণত পুনরাবৃত্ত হয়;
    লুপিংয়ের দুটি উপায় থাকা অবস্থায় লিনিয়ার ট্রভারসাল (লুপের মাধ্যমে) প্রাকৃতিক নয় not
    • রিকার্সিভ: এর অর্থ এমন একটি ফাংশন যা নিজেকে কল করে।
  3. পুরানো ফ্যাশনযুক্ত ভাষায়, মেমরি পরিচালনার জন্য ম্যানুয়াল মেমরি পরিচালনা প্রয়োজন requires
    • ম্যানুয়াল: মানে এটি আপনার নিজেরাই করতে হবে।
  4. আপনি যখন ম্যানুয়াল মেমরি পরিচালনা করবেন তখন আপনাকে গাছের প্রতিটি সদস্যকে মুক্ত করার জন্য অন্তর্নিহিত সিস্টেমটিকে প্রকৃতপক্ষে জিজ্ঞাসা করতে হবে।
    • বিনামূল্যে: বিশ্বব্যাপী স্মৃতি পুনরুদ্ধার করুন যাতে এটি পুনরায় ব্যবহার করা যায় এবং আপনার স্মৃতিশক্তি শেষ হয় না।
    • নিখরচায়: এটি ফাংশনটিতে কল করে free()এবং আপনি পুনরুদ্ধার করতে চান সেই পয়েন্টারটি পাস করার মাধ্যমে এটি করা হয়।
    • পয়েন্টার: এটি ভার্চুয়াল স্টিকের মতো। শেষে স্মৃতি। আপনি যখন মেমরি চাইবেন তখন আপনাকে একটি পয়েন্টার (ভার্চুয়াল স্টিক) দেওয়া হবে যার মেমরি রয়েছে has আপনার হয়ে গেলে আপনি পয়েন্টারটি ফিরিয়ে দেন (ভার্চুয়াল স্টিক)।

পুনরাবৃত্ত সমাধান:

freeTree(Node* node)
{
    freeTree(node->left);  
    freeTree(node->right);
    free(node);
}

তারপরে সমস্যাটি হ'ল পুনরাবৃত্তির অর্থ আপনি একই ক্রিয়াকলাপ বারবার কল করছেন। এটি স্ট্যাক বৃদ্ধি করে। স্ট্যাক বাড়ানো আরও মেমরি ব্যবহার করে। আপনি গাছকে মুক্ত করার কারণটি হ'ল আপনি আরও বেশি মেমরি ব্যবহার করে মেমরি ফিরিয়ে নিতে চান তা প্রতিরক্ষামূলক (এমনকি যদি আপনি উভয় স্মৃতি মেমরি ফিরে পান)।

শেষ পর্যন্ত প্রশ্ন:

সুতরাং উপরের পুনরাবৃত্ত সংস্করণটিকে রৈখিক সমাধানে রূপান্তরিত করার আশপাশে সমস্যা কেন্দ্রগুলি (যাতে আপনার স্মৃতি ব্যবহার করতে না হয়)।

নোড টাইপ দিন

typedef struct Node Node;
struct Node
{
    Node* left;
    Node* right;
};

এই নোডগুলির একটি গাছ মুক্ত করার জন্য একটি ফাংশন লিখুন।

সীমাবদ্ধতা:

  • পুনরাবৃত্তি ব্যবহার করতে পারবেন না (এমনকি অপ্রত্যক্ষভাবেও নয়)
  • ট্র্যাকিংয়ের জন্য কোনও গতিশীল স্থান বরাদ্দ করতে পারে না।

  • দ্রষ্টব্য একটি ও (এন) সমাধান আছে

বিজয়ী:

  1. সেরা জটিলতা।
  2. টাই ব্রেক 1: প্রথম জমা দেওয়া
  3. টাই ব্রেক 2: স্বল্প পরিমাণে অক্ষর।

উত্তর:


7

আমার কাছে ও (এন) এর খুব কাছাকাছি মনে হচ্ছে:

এটি গাছে প্রথম গভীরতা ->leftঅবলম্বন করে এবং পিতামাতার খোঁজ রাখতে ট্র্যাভার্সড নোডের পয়েন্টার ব্যবহার করে ।

struct Node * node = root;
struct Node * up = NULL;

while (node != NULL) {
    if (node->left != NULL) {
        struct Node * left = node->left;
        node->left = up;
        up = node;
        node = left;
    } else if (node->right != NULL) {
        struct Node * right = node->right;
        node->left = up;
        node->right = NULL;
        up = node;
        node = right;
    } else {
        if (up == NULL) {
            free(node);
            node = NULL;
        }
        while (up != NULL) {
            free(node);
            if (up->right != NULL) {
                node = up->right;
                up->right = NULL;
                break;
            } else {
                node = up;
                up = up->left;
            }
        }
    }
}

+1 একমাত্র উত্তরের জন্য টিক যোগ করুন। আমি নীচে উপস্থাপিত সমাধানের চেয়ে এটি কিছুটা জটিল তবে খুব ভাল।
মার্টিন ইয়র্ক

4

সি 99, 94, ও (এন)

সম্পাদনা করুন: প্রত্যেকে মনে হয় struct Nodeঠিক এডিটি Nodeহিসাবে উল্লেখ typedefকরেছেন, তাই আমিও করেছি।

এটি আসলে আমার প্রথম সি গল্ফ। সিগফাল্ট প্রচুর।

যাইহোক, এর জন্য সি 99 প্রয়োজন কারণ এটি লুপের প্রথম বিবৃতিটির জন্য একটি অভ্যন্তরে একটি ডিক্লোরেশন ব্যবহার করে।

void f(Node*n){for(Node*q;n;n=q)(q=n->left)?n->left=q->right,q->right=n:(q=n->right,free(n));}

এমনকি ব্যবহার না #define!

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

উদাহরণস্বরূপ, যদি আমরা গাছ দিয়ে শুরু করি

 1
/ \
2 3
 \
 4

অ্যালগরিদম পয়েন্টারগুলিকে পরিবর্তিত করবে যাতে গাছটি হবে

2
 \
 1
/ \
4 3

এখন আমরা শীর্ষস্থানীয় নোডটি সহজেই মুছতে পারি।


আমি টাইপিডেফ ব্যবহার করিনি কারণ আমার সি ++ ছিল (আপনি ভাষাগুলির মধ্যে এই ছোট পার্থক্যগুলি ভুলে যান)। আমি প্রশ্নটি আপডেট করেছি যাতে এটি সি এবং সি ++ তে একই কাজ করে।
মার্টিন ইয়র্ক

@ লোকিআস্টারি আমি আসলে সি ++ জানি না এবং আমি সম্প্রতি সি শিখতে শুরু করেছি। তবে আমি এর উত্তর দিতে যথেষ্ট জানতাম :-)
গর্বিত হাসেলেলার 25'14

1
আমি আপাতত একটি +1 করতে যাচ্ছি। তবে এখনও এটি কীভাবে কাজ করছে তা নিয়ে কাজ করি নি তাই টার্কির পরে ফিরে আসব। :-)
মার্টিন ইয়র্ক

@ লোকিআস্টারি এটি মূলত সত্যটি ব্যবহার করে যে সি কেবলমাত্র অভিব্যক্তি ব্যবহার করে কাজ করার জন্য অভিব্যক্তি এবং বিবৃতিগুলিকে একত্রিত করে
গর্বিত হাসেলেলার

1

সি / সি ++ / অবজেক্টিভ সি 126 টি অক্ষর (প্রয়োজনীয় ট্রেলিং নিউলাইন অন্তর্ভুক্ত)

#define b(t)(t->left||t->right)
void f(Node*r){while(r&&b(r)){Node**p=&r,*c=b(r);while(c)p=&c,c=b(c);free(*p);*p=0;}free(r);}

ও (এন) সময়ে চালায় না। তবে ওপি এর প্রয়োজন হয় না, সুতরাং আমার ও (এন 2 ) সমাধানটি এখানে।

অ্যালগরিদম: মূল থেকে একটি পাতায় হাঁটুন। এটিকে মুক্ত কর. কোনও পাতা না পাওয়া পর্যন্ত পুনরাবৃত্তি করুন। শিকড় ছেড়ে দিন।

Ungolfed:

void freeTree (Node * root) {
    while (root && (root->left || root->right)) {
        Node ** prev = &root;
        Node * curr = root->left || root->right;
        while (curr != 0) {
            prev = &curr;
            curr = curr->left || curr->right;
        }
        free(*prev);
        *prev = 0;
    }
    free(root);
}

দুর্ভাগ্যক্রমে যে কাজ করবে না। আপনি পাতাটি পয়েন্টারটি মুক্ত করার আগে NULL এ সেট করবেন না। সুতরাং আপনি অবিচ্ছিন্নভাবে একই পাতা নোডকে মুক্ত রাখবেন এবং আপনি যে গাছটি মুক্ত করবেন সেখানে কখনও পৌঁছাতে পারবেন না।
মার্টিন ইয়র্ক

@ লোকিস্টারি: বাগটি লক্ষ্য করার জন্য ধন্যবাদ। এটি এখনই ঠিক করা উচিত (যদিও আমি কোডটি পরীক্ষা করি নি)।
টমাস এডিং

1

সি ++৯ ও (এন)

তালিকার জিনিসটি এখানে তালিকার সাথে শৃঙ্খলার জন্য দুর্দান্ত তবে ক্রমবর্ধমান স্তরক্রমগুলি উপরে ওঠা যাচ্ছে না। ইউজার 300 এটি পরিচালনা করেছে (আমি মুগ্ধ) তবে কোডটি পড়া শক্ত।

সমাধানটি হল গাছটিকে তালিকায় রূপান্তর করা।
কৌশলটি হ'ল আপনার নোডগুলি মোছার একই সাথে এটি করা।

void freeNode(Node* t)
{
    if (t == NULL)
    {   return;
    }

    // Points at the bottom left node.
    // Any right nodes are added to the bottom left as we go down
    // this progressively flattens the tree into a list as we go.    
    Node* bottomLeft    = findBottomLeft(t);


    while(t != NULL)
    {
        // Technically we don't need the if (it works fine without)
        // But it makes the code easier to reason about with it here.
        if (t->right != NULL)
        {
            bottomLeft->left = t->right;
            bottomLeft = findBottomLeft(bottomLeft);
        }
        // Now just free the curent node
        Node*   old = t;
        t = t->left;
        free(old);
    }
}

Node* findBottomLeft(Node* t)
{
    while(t->left != NULL)
    {
        t = t->left;
    }
    return t;
}

গল্ফ সংস্করণ

void f(Node*t){Node*o,*l=t;for(;t;free(o)){for(;l->left;l=l->left);l->left=t->right;o=t;t=t->left;}}

গল্ফ প্রসারিত

void f(Node* t)
{
        Node*o,*l    = t;

        for(;t;free(o))
        {
            for(;l->left;l = l->left);
            l->left = t->right;
            o = t;
            t = t->left;
        }
}

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