বাইনারি গাছ ভারসাম্যযুক্ত কীভাবে তা নির্ধারণ করবেন?


113

সেই স্কুল বছরগুলিতে কিছুটা সময় কেটে গেছে। হাসপাতালে আইটি বিশেষজ্ঞ হিসাবে চাকরি পেয়েছেন। এখন কিছু আসল প্রোগ্রামিং করার জন্য সরানোর চেষ্টা করা হচ্ছে। আমি এখন বাইনারি গাছগুলিতে কাজ করছি এবং আমি ভাবছিলাম যে গাছটি উচ্চতা-ভারসাম্যযুক্ত কিনা তা নির্ধারণের সেরা উপায় কী হবে?

আমি এর পাশাপাশি কিছু ভাবছিলাম:

public boolean isBalanced(Node root){
    if(root==null){
        return true;  //tree is empty
    }
    else{
        int lh = root.left.height();
        int rh = root.right.height();
        if(lh - rh > 1 || rh - lh > 1){
            return false;
        }
    }
    return true;
}

এটি কি একটি ভাল বাস্তবায়ন? নাকি আমি কিছু মিস করছি?


আপনি যদি গ্রাফিক সহ ডোনাল ফেলোর এসকিআই
ব্যবহারকারী 7643681

1
ভাল উত্তর, আমাকে মার্কিন যুক্তরাষ্ট্রে প্রবেশ করতে সাহায্য করেছিল। (জোকস)
হেনরি

উত্তর:


165

অন্য কিছু অনুসন্ধান করার সময় এই পুরানো প্রশ্নটি দেখে হোঁচট খেয়েছে। আমি লক্ষ্য করেছি যে আপনি কখনই সম্পূর্ণ উত্তর পান নি।

এই সমস্যাটি সমাধানের উপায় হ'ল আপনি যে ফাংশনটি লেখার চেষ্টা করছেন তার জন্য একটি স্পেসিফিকেশন লিখে শুরু করা।

নির্দিষ্টকরণ: একটি সুগঠিত বাইনারি গাছটিকে "উচ্চতা-ভারসাম্যপূর্ণ" বলা হয় যদি (1) এটি খালি থাকে, বা (2) এর বাম এবং ডান শিশুদের উচ্চতা ভারসাম্যযুক্ত এবং বাম গাছের উচ্চতা 1 এর মধ্যে 1 টির মধ্যে রয়েছে ডান গাছের উচ্চতা।

আপনার স্পেসিফিকেশন এখন, কোড লিখতে তুচ্ছ। শুধু স্পেসিফিকেশন অনুসরণ করুন:

IsHeightBalanced(tree)
    return (tree is empty) or 
           (IsHeightBalanced(tree.left) and
            IsHeightBalanced(tree.right) and
            abs(Height(tree.left) - Height(tree.right)) <= 1)

আপনার পছন্দের প্রোগ্রামিং ভাষায় এটি অনুবাদ করা তুচ্ছ হওয়া উচিত।

বোনাস অনুশীলন : উচ্চতা গণনা করার সময় এই নিষ্পাপ কোড স্কেচটি গাছটিকে অনেক বেশি বার ঘুরিয়ে দেয়। আপনি কি আরও দক্ষ করতে পারেন?

সুপার বোনাস অনুশীলন : ধরুন গাছটি ব্যাপকভাবে ভারসাম্যহীন। যেমন, এক মিলিয়ন মিলিয়ন নোড এবং অন্যদিকে তিনটি গভীর। এমন কোনও দৃশ্য আছে যেখানে এই অ্যালগরিদম স্ট্যাকটি ফুটিয়ে তোলে? আপনি কি বাস্তবায়নটি ঠিক করতে পারেন যাতে এটি কোনও পরিমাণে ভারসাম্যহীন গাছ দেওয়া সত্ত্বেও স্ট্যাকটি কখনও আঘাত করে না?

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

আমার সংজ্ঞা থেকে একটিও কম কঠোর হতে পারে; যে কেউ বলতে পারে যে সুষম গাছ এমন একটি যাতে প্রতিটি শাখায় খালি গাছে সর্বাধিক পথের দৈর্ঘ্য দুটি, তিন বা অন্য কোনও ধ্রুবকের দ্বারা পৃথক হয় না। বা সর্বাধিক পাথের দৈর্ঘ্য হ'ল ন্যূনতম পাথ দৈর্ঘ্যের কিছু অংশ, যেমন দেড় বা চতুর্থাংশ।

এটি আসলে সাধারণত কিছু যায় আসে না। যে কোনও ট্রি-ব্যালেন্সিং অ্যালগরিদমের মূল বিষয়টি হ'ল এটি নিশ্চিত করা যে আপনি যেখানে একদিকে দশ মিলিয়ন নোড এবং অন্যদিকে তিনটি নোড রয়েছে সেই পরিস্থিতিতে আপনার গতিবেগ না ঘটে। তাত্ত্বিকভাবে ডোনালের সংজ্ঞাটি যথাযথ, তবে বাস্তবে এটি গাছের ভারসাম্যযুক্ত অ্যালগরিদম নিয়ে আসা একটি ব্যথা যা সেই স্তরের কঠোরতার সাথে মিলিত হয়। পারফরম্যান্সের সঞ্চয়গুলি সাধারণত প্রয়োগের ব্যয়টিকে ন্যায়সঙ্গত করে না। বাস্তবে সামান্যতম পার্থক্য তৈরি করে এমন একটি ভারসাম্য বজায় রাখতে আপনি অযথা গাছের পুনর্বিন্যাস করতে প্রচুর সময় ব্যয় করেন। তাত্ত্বিকভাবে পুরোপুরি ভারসাম্যযুক্ত গাছের মধ্যে বিশটি গ্রহণ করতে পারলে কয়েক মিলিয়ন নোডের অপূর্ণতা-ভারসাম্যপূর্ণ গাছের সর্বাধিক পাতায় চলার জন্য যদি চল্লিশটি শাখা লাগে তবে কে তা চিন্তা করে? মুল বক্তব্যটি এটি কখনও মিলিয়ন নেয় না। এক মিলিয়ন সবচেয়ে খারাপ অবস্থার থেকে চল্লিশের সবচেয়ে খারাপ অবস্থানে পৌঁছানো সাধারণত যথেষ্ট ভাল; আপনি সর্বোত্তম ক্ষেত্রে যেতে হবে না।


19
শুধুমাত্র সঠিক উত্তরের জন্য +1, আমি বিশ্বাস করতে পারি না যে 8 মাস কেউ এই উত্তর দিতে সক্ষম হয় নি ...
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

1
নীচে "অনুশীলন" এর উত্তর ...
পটোটো ওয়াটার

উত্তর বোনাস অনুশীলন নীচে।
ব্রায়ান

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

তাত্ত্বিকভাবে, আমাকে ডোনাল ফেলো'র সংজ্ঞাটি এখনও বজায় রাখতে হবে।
ধ্রুব গায়রোলা

26

ভারসাম্য সত্যই একটি সূক্ষ্ম সম্পত্তি; আপনি মনে করেন এটি কী তা আপনি জানেন তবে এটি ভুল হওয়া খুব সহজ। বিশেষত, এমনকি এরিক লিপার্টের (ভাল) উত্তরটি বন্ধ। কারণ উচ্চতার ধারণাটি যথেষ্ট নয়। আপনার একটি গাছের ন্যূনতম এবং সর্বাধিক উচ্চতার ধারণা থাকা দরকার (যেখানে নূন্যতম উচ্চতা হ'ল মূল থেকে কোনও পাতা পর্যন্ত কয়েকটি ধাপের সংখ্যা এবং সর্বাধিক ... ভাল, আপনি ছবিটি পান)। এটি দেওয়া, আমরা এইটিকে ভারসাম্য নির্ধারণ করতে পারি:

যে গাছটি যে কোনও শাখার সর্বোচ্চ উচ্চতা কোনও শাখার নূন্যতম উচ্চতার চেয়ে বেশি নয় one

(এটি প্রকৃতপক্ষে বোঝায় যে শাখাগুলি নিজেই ভারসাম্যযুক্ত; আপনি সর্বোচ্চ এবং সর্বনিম্ন উভয়ের জন্য একই শাখা বেছে নিতে পারেন))

এই সম্পত্তিটি যাচাই করার জন্য আপনাকে যা করতে হবে তা হ'ল বর্তমান গভীরতার উপর নজর রাখা একটি সাধারণ ট্রি ট্রভারসাল al প্রথমবার আপনি ব্যাকট্র্যাক করুন, এটি আপনাকে একটি বেসলাইন গভীরতা দেয়। এর পরে প্রতিবার যখন আপনি ব্যাকট্র্যাক করেন, আপনি নতুন লাইনের সাথে বেসলাইনটির তুলনা করেন

  • যদি এটি বেসলাইনের সমান হয় তবে আপনি কেবল চালিয়ে যান
  • যদি এটি একের বেশি হয় তবে গাছটি ভারসাম্যপূর্ণ নয়
  • যদি এটি বন্ধ থাকে তবে আপনি এখন ভারসাম্যের জন্য পরিধিটি জানেন এবং পরবর্তী সমস্ত গভীরতা (আপনি যখন ব্যাকট্র্যাকের দিকে যাচ্ছেন) অবশ্যই প্রথম বা দ্বিতীয় মান হতে হবে।

কোডে:

class Tree {
    Tree left, right;
    static interface Observer {
        public void before();
        public void after();
        public boolean end();
    }
    static boolean traverse(Tree t, Observer o) {
        if (t == null) {
            return o.end();
        } else {
            o.before();
            try {
                if (traverse(left, o))
                    return traverse(right, o);
                return false;
            } finally {
                o.after();
            }
        }
    }
    boolean balanced() {
        final Integer[] heights = new Integer[2];
        return traverse(this, new Observer() {
            int h;
            public void before() { h++; }
            public void after() { h--; }
            public boolean end() {
                if (heights[0] == null) {
                    heights[0] = h;
                } else if (Math.abs(heights[0] - h) > 1) {
                    return false;
                } else if (heights[0] != h) {
                    if (heights[1] == null) {
                        heights[1] = h;
                    } else if (heights[1] != h) {
                        return false;
                    }
                }
                return true;
            }
        });
    }
}

আমি মনে করি আপনি পর্যবেক্ষক প্যাটার্নটি ব্যবহার না করেই এটি করতে পারতেন তবে এইভাবে যুক্তি করা আমার পক্ষে সহজ মনে হয়েছে।


[সম্পাদনা]: আপনি কেবল প্রতিটি পক্ষের উচ্চতা নিতে পারবেন না কেন। এই গাছটি বিবেচনা করুন:

        /\
       /  \
      /    \
     /      \_____
    /\      /     \_
   /  \    /      / \
  /\   C  /\     /   \
 /  \    /  \   /\   /\
A    B  D    E F  G H  J

ঠিক আছে, একটু নোংরা, কিন্তু রুট প্রতিটি পাশ সুষম হয়: Cগভীরতা 2, হয় A, B, D, Eগভীরতা 3, এবং F, G, H, Jগভীরতা 4. বাম শাখার উচ্চতা 2 (উচ্চতা স্মরণ হিসাবে আপনি ঢুকা কমে যায় শাখা), ডান শাখার উচ্চতা 3. এখনও সামগ্রিক গাছ হয় না সুষম সেখানে মধ্যে 2 উচ্চতা মধ্যে একটি পার্থক্য আছে Cএবং F। আপনার একটি মিনিম্যাক্স স্পেসিফিকেশন প্রয়োজন (যদিও আসল অ্যালগরিদম কম জটিল হতে পারে কারণ সেখানে কেবল দুটি অনুমোদিত উচ্চতা থাকতে হবে)।


আহ, ভাল কথা। আপনার কাছে এমন একটি গাছ থাকতে পারে যা h (LL) = 4, h (LR) = 3, h (RL) = 3, h (RR) = 2। সুতরাং, এইচ (এল) = 4 এবং এইচ (আর) = 3, সুতরাং এটি পূর্ববর্তী অ্যালগরিদমের সাথে সুষম মনে হবে তবে সর্বোচ্চ / মিনিটের 4/2 গভীরতার সাথে এটি ভারসাম্যপূর্ণ নয়। এটি সম্ভবত একটি ছবি দিয়ে আরও বোধগম্য হবে।
টিম

1
এটাই আমি স্রেফ যুক্ত করেছি (বিশ্বের নবীনতম এএসসিআইআই গ্রাফিক ট্রি সহ)।
ডোনাল ফেলো

@ ডোনালফেলোস: আপনি বাম শাখার উচ্চতা ২ বলে উল্লেখ করেছেন তবে বাম শাখায় মূল এবং পাতা সহ 4 টি নোড রয়েছে এ ক্ষেত্রে উচ্চতা 3 হবে সঠিক
মস্তিষ্কে ঝড় 19

22

এটি কেবলমাত্র গাছের শীর্ষ স্তরের ভারসাম্যপূর্ণ কিনা তা নির্ধারণ করে। এটি হল আপনার মাঝখানে কিছুই নেই, ডানদিকে খুব বাম এবং ডানদিকে দীর্ঘ দুটি ডানা যুক্ত একটি গাছ থাকতে পারে এবং এটি সত্য হবে। আপনাকে পুনরাবৃত্তভাবে পরীক্ষা করে দেখতে হবে root.leftএবং root.rightসত্য ফিরে আসার আগে সেগুলি অভ্যন্তরীণভাবে সুষম রয়েছে কিনা তা দেখতে।


তবে কোডটির সর্বাধিক এবং ন্যূনতম উচ্চতা পদ্ধতি থাকলে এটি বিশ্বব্যাপী সুষম হয় তবে এটি স্থানীয়ভাবেও সুষম হবে।
এরি

22

বোনাস অনুশীলন সাড়া। সহজ সমাধান। স্পষ্টতই বাস্তব বাস্তবায়নের ক্ষেত্রে ব্যবহারকারীরা তাদের প্রতিক্রিয়াতে উচ্চতা অন্তর্ভুক্ত করার প্রয়োজন এড়াতে এই বা অন্য কোনও জিনিসটি গুটিয়ে রাখতে পারে।

IsHeightBalanced(tree, out height)
    if (tree is empty)
        height = 0
        return true
    balance = IsHeightBalanced(tree.left, heightleft) and IsHeightBalanced(tree.right, heightright)
    height = max(heightleft, heightright)+1
    return balance and abs(heightleft - heightright) <= 1     

গাছটি কয়েক'শ স্তরের চেয়ে বেশি যদি বড় হয় তবে আপনি স্ট্যাকওভারফ্লো ব্যতিক্রম পাবেন। আপনি এটি দক্ষতার সাথে করেছেন তবে এটি মাঝারি বা বড় আকারের ডেটা সেটগুলি পরিচালনা করে না।
এরিক লেসচিনস্কি

এই সিউডোকোডটি কি আপনি সবেমাত্র নিয়ে এসেছেন বা এটি একটি বাস্তব ভাষা? (আমি " out height" ভেরিয়েবল স্বরলিপিটি বোঝাতে চাইছি )
কেপ

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

20

অর্ডার সলিউশন পোস্ট করুন, গাছটি একবারে অতিক্রম করুন। সময়ের জটিলতা হ'ল ও (এন), স্থান হ'ল (1), এটি টপ-ডাউন সমাধানের চেয়ে ভাল। আমি আপনাকে একটি জাভা সংস্করণ বাস্তবায়ন দিচ্ছি।

public static <T> boolean isBalanced(TreeNode<T> root){
    return checkBalance(root) != -1;
}

private static <T> int checkBalance(TreeNode<T> node){
    if(node == null) return 0;
    int left = checkBalance(node.getLeft());

    if(left == -1) return -1;

    int right = checkBalance(node.getRight());

    if(right == -1) return -1;

    if(Math.abs(left - right) > 1){
        return -1;
    }else{
        return 1 + Math.max(left, right);
    }
}

4
চমৎকার সমাধান, তবে স্থান জটিলতা হ'ল (এইচ) হওয়া উচিত যেখানে এইচ গাছের উচ্চতা। কারণ পুনরাবৃত্তির জন্য স্ট্যাক বরাদ্দ।
লেগরাস

কী left == -1মানে? কখন যে ঘটনা হবে? left == -1বাম শিশুদের সমস্ত সাবট্রিস ভারসাম্যহীন হলে আমরা কি পুনরাবৃত্ত কলটি বোঝায় তা সত্য?
অ্যাস্পেন

left == 1মানে বাম সাবট্রি ভারসাম্যহীন, তারপরে পুরো গাছ ভারসাম্যহীন। আমাদের আর ডান সাবট্রি চেক করতে হবে না, এবং ফিরে আসতে পারে-1
22-15

সময়ের জটিলতা হ'ল (এন) কারণ আপনাকে সমস্ত উপাদানগুলির মধ্য দিয়ে যেতে হবে। এবং, যদি আপনার এক্স নোড থাকে এবং ভারসাম্য পরীক্ষা করতে y সময় লাগে; আপনার যদি 2x নোড থাকে তবে ভারসাম্য পরীক্ষা করতে 2y সময় লাগবে। সব ঠিক আছে?
জ্যাক

অঙ্কন সহ ভাল ব্যাখ্যা এখানে: অ্যালগরিদমস.টিউটোরিয়ালহরিজন.
com/…

15

উচ্চতা-ভারসাম্য বাইনারি গাছের সংজ্ঞাটি হ'ল:

বাইনারি ট্রি যেখানে প্রতিটি নোডের দুটি সাবট্রির উচ্চতা 1 এর বেশি হয় না।

সুতরাং, একটি খালি বাইনারি গাছ সর্বদা উচ্চতা-ভারসাম্যযুক্ত।
একটি খালি খালি বাইনারি গাছ উচ্চতা-ভারসাম্যযুক্ত যদি:

  1. এর বাম সাবট্রিটি উচ্চতা-ভারসাম্যযুক্ত।
  2. এটির ডান সাবট্রিটি উচ্চতা-ভারসাম্যযুক্ত।
  3. বাম এবং ডান সাবট্রির উচ্চতার মধ্যে পার্থক্য 1 এর বেশি নয়।

গাছটি বিবেচনা করুন:

    A
     \ 
      B
     / \
    C   D

যেমন দেখা গেছে এর বাম সাবট্রিটি Aউচ্চতা-ভারসাম্যযুক্ত (এটি খালি রয়েছে) এবং ঠিক এর ডান সাবট্রিও। বাম-সাবট্রির 0উচ্চতা এবং ডান উপ-গাছের উচ্চতা হিসাবে 3 শর্তটি পূরণ না হওয়ায় এখনও গাছটি উচ্চতা-ভারসাম্যপূর্ণ নয় 2

বাম এবং ডান উপ-গাছের উচ্চতা সমান হলেও নীচের গাছটি উচ্চতা ভারসাম্যপূর্ণ নয়। আপনার বিদ্যমান কোড এটির জন্য সত্য ফিরে আসবে।

       A
     /  \ 
    B    C
   /      \
  D        G
 /          \
E            H

কথাটি তাই প্রতি খুব গুরুত্বপূর্ণ।

এটি কাজ করবে:

int height(treeNodePtr root) {
        return (!root) ? 0: 1 + MAX(height(root->left),height(root->right));
}

bool isHeightBalanced(treeNodePtr root) {
        return (root == NULL) ||
                (isHeightBalanced(root->left) &&
                isHeightBalanced(root->right) &&
                abs(height(root->left) - height(root->right)) <=1);
}

আইডিয়ন লিঙ্ক


সুতরাং এই উত্তরটি আমাকে অনেক সাহায্য করেছিল। যাইহোক, আমি নিখরচায় [এমআইটি ইন্ট্রো টু অ্যালগোরিদম কোর্স] শর্তটি বিপরীত বলে মনে করেছি Page পৃষ্ঠা 4 একটি আরবি গাছ দেখায় যেখানে বাম শাখার উচ্চতা 2 এবং ডান শাখা 4 আপনি কি আমাকে কিছু ব্যাখ্যা দিতে পারবেন? সম্ভবত আমি একটি সাবট্রির সংজ্ঞা পাই না। [১]: ocw.mit.edu/courses/electrical-engineering-
and- কম্পিউটার কম্পিউটার-

পার্থক্যটি কোর্স নোটগুলিতে এই সংজ্ঞা থেকে এসেছে বলে মনে হচ্ছে। যে কোনও নোড x থেকে বংশজাত পাতায় সমস্ত সরল পথগুলির একই সংখ্যক কালো নোড = কালো উচ্চতা (এক্স)
i8abug

কেবল অনুসরণ করতে, আমি একটি সংজ্ঞা পেয়েছি যা আপনার উত্তরটিতে বিন্দু (3) পরিবর্তিত করে "প্রতিটি পাতাগুলি 'অন্য কোনও পাতার তুলনায় মূল থেকে' নির্দিষ্ট দূরত্বের চেয়ে বেশি দূরে নয় '" এটি উভয় ক্ষেত্রেই সন্তুষ্ট বলে মনে হচ্ছে। এখানে কয়েকটি এলোমেলো কোর্স ওয়েয়ারের লিঙ্কটি দেওয়া হয়েছে
i8abug

8

বাইনারি ট্রি যদি ভারসাম্যযুক্ত হয় বা না থাকে তবে স্তর স্তর ট্র্যাভারসাল দ্বারা পরীক্ষা করা যায়:

private boolean isLeaf(TreeNode root) {
    if (root.left == null && root.right == null)
        return true;
    return false;
}

private boolean isBalanced(TreeNode root) {
    if (root == null)
        return true;
    Vector<TreeNode> queue = new Vector<TreeNode>();
    int level = 1, minLevel = Integer.MAX_VALUE, maxLevel = Integer.MIN_VALUE;
    queue.add(root);
    while (!queue.isEmpty()) {
        int elementCount = queue.size();
        while (elementCount > 0) {
            TreeNode node = queue.remove(0);
            if (isLeaf(node)) {
                if (minLevel > level)
                    minLevel = level;
                if (maxLevel < level)
                    maxLevel = level;
            } else {
                if (node.left != null)
                    queue.add(node.left);
                if (node.right != null)
                    queue.add(node.right);
            }
            elementCount--;
        }
        if (abs(maxLevel - minLevel) > 1) {
            return false;
        }
        level++;
    }

    return true;
}

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

7

এটি আসলে যত জটিল তার চেয়ে জটিল করে তোলা হচ্ছে।

অ্যালগরিদম নিম্নরূপ:

  1. সর্বোচ্চ স্তরের নোডের A = গভীরতা দিন
  2. বি = নিম্নতম স্তরের নোডের গভীরতা দিন depth

  3. যদি অ্যাবস (এবি) <= 1 হয়, তবে গাছটি ভারসাম্যপূর্ণ


সরল ও সোজা!
ওয়াসিম থাব্রাজ

3
দুটি সমস্যা, এটি যতটা দক্ষ তা হতে পারে না, আপনি পুরো গাছের উপর দিয়ে দুটি পাস করছেন। এবং যে গাছগুলির বামে একটি নোড রয়েছে এবং হাজারে ডানদিকে, আপনি অকারণে পুরো জিনিসটি দিয়ে যান, যখন আপনি 3 টি চেক পরে থামতে পারতেন।
এরিক লেসচিনস্কি

5

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

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


4

দ্রষ্টব্য 1: যে কোনও উপ-গাছের উচ্চতা কেবল একবার গণনা করা হয়।

দ্রষ্টব্য 2: বাম উপ-গাছ যদি ভারসাম্যহীন থাকে তবে সম্ভাব্যভাবে মিলিয়ন উপাদান রয়েছে এমন ডান উপ-গাছের গণনা বাদ দেওয়া হয়।

// return height of tree rooted at "tn" if, and only if, it is a balanced subtree
// else return -1
int maxHeight( TreeNode const * tn ) {
    if( tn ) {
        int const lh = maxHeight( tn->left );
        if( lh == -1 ) return -1;
        int const rh = maxHeight( tn->right );
        if( rh == -1 ) return -1;
        if( abs( lh - rh ) > 1 ) return -1;
        return 1 + max( lh, rh );
    }
    return 0;
}

bool isBalanced( TreeNode const * root ) {
    // Unless the maxHeight is -1, the subtree under "root" is balanced
    return maxHeight( root ) != -1;
}

3

ব্যালেন্সিং সাধারণত প্রতিটি দিকের দীর্ঘতম দৈর্ঘ্যের উপর নির্ভর করে। উপরের অ্যালগরিদম আপনার জন্য এটি করতে যাচ্ছে না।

আপনি কি বাস্তবায়নের চেষ্টা করছেন? চারপাশে স্ব-ভারসাম্যযুক্ত গাছ রয়েছে (এভিএল / লাল-কালো)। আসলে জাভা গাছগুলি ভারসাম্যপূর্ণ।


3

এটি যদি আপনার কাজের জন্য হয় তবে আমার পরামর্শ:

  1. চাকা পুনরুদ্ধার করবেন না এবং
  2. সিটিএস ব্যবহার / কিনুনবিটসের সাথে পরিবর্তে ।
  3. ব্যবসায়ের সমস্যা সমাধানের জন্য আপনার সময় / শক্তি সাশ্রয় করুন।

3
public boolean isBalanced(TreeNode root)
{
    return (maxDepth(root) - minDepth(root) <= 1);
}

public int maxDepth(TreeNode root)
{
    if (root == null) return 0;

    return 1 + max(maxDepth(root.left), maxDepth(root.right));
}

public int minDepth (TreeNode root)
{
    if (root == null) return 0;

    return 1 + min(minDepth(root.left), minDepth(root.right));
}

আমি মনে করি এই সমাধানটি সঠিক নয় I যদি আপনি এমন একটি গাছ পাস করেন যা একটি নোড অর্থাৎ একটি রুট রয়েছে তবে এটি ম্যাক্সডেপথ 1(মিনিডেপথের জন্য একই) হিসাবে ফিরে আসবে। যদিও সঠিক গভীরতা হওয়া উচিত 0A গাছের মূলের সর্বদা 0গভীরতা থাকে
ক্র্যাটিলাস

3

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

using System;
using System.Linq;
using System.Text;

namespace BalancedTree
{
    class Program
    {
        public static void Main()
        {
            //Value Gathering
            Console.WriteLine(RunTreeTests(new[] { 0 }));
            Console.WriteLine(RunTreeTests(new int[] { }));

            Console.WriteLine(RunTreeTests(new[] { 0, 1, 2, 3, 4, -1, -4, -3, -2 }));
            Console.WriteLine(RunTreeTests(null));
            Console.WriteLine(RunTreeTests(new[] { 10, 8, 12, 8, 4, 14, 8, 10 }));
            Console.WriteLine(RunTreeTests(new int[] { 20, 10, 30, 5, 15, 25, 35, 3, 8, 12, 17, 22, 27, 32, 37 }));

            Console.ReadKey();
        }

        static string RunTreeTests(int[] scores)
        {
            if (scores == null || scores.Count() == 0)
            {
                return null;
            }

            var tree = new BinarySearchTree();

            foreach (var score in scores)
            {
                tree.InsertScore(score);
            }

            Console.WriteLine(tree.IsBalanced());

            var sb = tree.GetBreadthWardsTraversedNodes();

            return sb.ToString(0, sb.Length - 1);
        }
    }

    public class Node
    {
        public int Value { get; set; }
        public int Count { get; set; }
        public Node RightChild { get; set; }
        public Node LeftChild { get; set; }
        public Node(int value)
        {
            Value = value;
            Count = 1;
        }

        public override string ToString()
        {
            return Value + ":" + Count;
        }

        public bool IsLeafNode()
        {
            return LeftChild == null && RightChild == null;
        }

        public void AddValue(int value)
        {
            if (value == Value)
            {
                Count++;
            }
            else
            {
                if (value > Value)
                {
                    if (RightChild == null)
                    {
                        RightChild = new Node(value);
                    }
                    else
                    {
                        RightChild.AddValue(value);
                    }
                }
                else
                {
                    if (LeftChild == null)
                    {
                        LeftChild = new Node(value);
                    }
                    else
                    {
                        LeftChild.AddValue(value);
                    }
                }
            }
        }
    }

    public class BinarySearchTree
    {
        public Node Root { get; set; }

        public void InsertScore(int score)
        {
            if (Root == null)
            {
                Root = new Node(score);
            }
            else
            {
                Root.AddValue(score);
            }
        }

        private static int _heightCheck;
        public bool IsBalanced()
        {
            _heightCheck = 0;
            var height = 0;
            if (Root == null) return true;
            var result = CheckHeight(Root, ref height);
            height--;
            return (result && height == 0);
        }

        private static bool CheckHeight(Node node, ref int height)
        {
            height++;
            if (node.LeftChild == null)
            {
                if (node.RightChild != null) return false;
                if (_heightCheck != 0) return _heightCheck == height;
                _heightCheck = height;
                return true;
            }
            if (node.RightChild == null)
            {
                return false;
            }

            var leftCheck = CheckHeight(node.LeftChild, ref height);
            if (!leftCheck) return false;
            height--;
            var rightCheck = CheckHeight(node.RightChild, ref height);
            if (!rightCheck) return false;
            height--;
            return true;
        }


        public StringBuilder GetBreadthWardsTraversedNodes()
        {
            if (Root == null) return null;
            var traversQueue = new StringBuilder();
            traversQueue.Append(Root + ",");
            if (Root.IsLeafNode()) return traversQueue;
            TraversBreadthWards(traversQueue, Root);
            return traversQueue;
        }

        private static void TraversBreadthWards(StringBuilder sb, Node node)
        {
            if (node == null) return;
            sb.Append(node.LeftChild + ",");
            sb.Append(node.RightChild + ",");
            if (node.LeftChild != null && !node.LeftChild.IsLeafNode())
            {
                TraversBreadthWards(sb, node.LeftChild);
            }
            if (node.RightChild != null && !node.RightChild.IsLeafNode())
            {
                TraversBreadthWards(sb, node.RightChild);
            }
        }
    }
}

আমি বুঝতে পারছি না যে উত্তর পোস্ট করার 2 মিনিটের মধ্যে কেউ এই উত্তরটিকে নেতিবাচকভাবে কীভাবে ভোট দিতে পারে ?? নেতিবাচক ভোট ঠিক আছে তবে আপনি কি দয়া করে ব্যাখ্যা করতে পারেন যে এই সমাধানটিতে কী দোষ আছে?
এসবিপি

2
#include <iostream>
#include <deque>
#include <queue>

struct node
{
    int data;
    node *left;
    node *right;
};

bool isBalanced(node *root)
{
    if ( !root)
    {
        return true;
    }

    std::queue<node *> q1;
    std::queue<int>  q2;
    int level = 0, last_level = -1, node_count = 0;

    q1.push(root);
    q2.push(level);

    while ( !q1.empty() )
    {
        node *current = q1.front();
        level = q2.front();

        q1.pop();
        q2.pop();

        if ( level )
        {
            ++node_count;
        }

                if ( current->left )
                {
                        q1.push(current->left);
                        q2.push(level + 1);
                }

                if ( current->right )
                {
                        q1.push(current->right);
                        q2.push(level + 1);
                }

        if ( level != last_level )
        {
            std::cout << "Check: " << (node_count ? node_count - 1 : 1) << ", Level: " << level << ", Old level: " << last_level << std::endl;
            if ( level && (node_count - 1) != (1 << (level-1)) )
            {
                return false;
            }

            last_level = q2.front();
            if ( level ) node_count = 1;
        }
    }

    return true;
}

int main()
{
    node tree[15];

    tree[0].left  = &tree[1];
    tree[0].right = &tree[2];
    tree[1].left  = &tree[3];
    tree[1].right = &tree[4];
    tree[2].left  = &tree[5];
    tree[2].right = &tree[6];
    tree[3].left  = &tree[7];
    tree[3].right = &tree[8];
    tree[4].left  = &tree[9];   // NULL;
    tree[4].right = &tree[10];  // NULL;
    tree[5].left  = &tree[11];  // NULL;
    tree[5].right = &tree[12];  // NULL;
    tree[6].left  = &tree[13];
    tree[6].right = &tree[14];
    tree[7].left  = &tree[11];
    tree[7].right = &tree[12];
    tree[8].left  = NULL;
    tree[8].right = &tree[10];
    tree[9].left  = NULL;
    tree[9].right = &tree[10];
    tree[10].left = NULL;
    tree[10].right= NULL;
    tree[11].left = NULL;
    tree[11].right= NULL;
    tree[12].left = NULL;
    tree[12].right= NULL;
    tree[13].left = NULL;
    tree[13].right= NULL;
    tree[14].left = NULL;
    tree[14].right= NULL;

    std::cout << "Result: " << isBalanced(tree) << std::endl;

    return 0;
}

আপনি কিছু মন্তব্য যুক্ত করতে চাইতে পারেন
jgauffin

2

RE: @ লেবি-অর্ডার ট্র্যাভারসাল করতে বিএফএস ব্যবহার করে ভাগ্যবানদের সমাধান solution

আমরা গাছটিকে অতিক্রম করি এবং ভার্স ন্যূনতম / সর্বাধিক-স্তরের একটি রেফারেন্স রাখি যা নোড একটি পাতা ন্যূনতম স্তরের বর্ণনা করে।

আমি বিশ্বাস করি যে @ লাকি সমাধানটিতে একটি পরিবর্তন প্রয়োজন requires @ কোডডটিক্টের পরামর্শ অনুসারে নোড একটি পাতা কিনা তা পরীক্ষা না করে আমাদের অবশ্যই বাম বা ডান বাচ্চাদের নাল (উভয়ই নয়) পরীক্ষা করতে হবে। অন্যথায়, অ্যালগরিদম এটিকে একটি বৈধ ভারসাম্য গাছ হিসাবে বিবেচনা করবে:

     1
    / \
   2   4
    \   \
     3   1

পাইথনে:

def is_bal(root):
    if root is None:
        return True

    import queue

    Q = queue.Queue()
    Q.put(root)

    level = 0
    min_level, max_level = sys.maxsize, sys.minsize

    while not Q.empty():
        level_size = Q.qsize()

        for i in range(level_size):
            node = Q.get()

            if not node.left or node.right:
                min_level, max_level = min(min_level, level), max(max_level, level)

            if node.left:
                Q.put(node.left)
            if node.right:
                Q.put(node.right)

        level += 1

        if abs(max_level - min_level) > 1:
            return False

    return True

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

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


1

ঠিক আছে, আপনার বাম এবং ডানগুলির উচ্চতা নির্ধারণ করার একটি উপায় প্রয়োজন এবং যদি বাম এবং ডান ভারসাম্যপূর্ণ হয়।

এবং আমি ঠিক করেছি return height(node->left) == height(node->right);

একটি heightফাংশন লিখতে হিসাবে , পড়ুন: পুনরাবৃত্তি বোঝা


3
আপনি বাম এবং ডান উচ্চতা 1 এর মধ্যে হতে চান, অগত্যা সমান নয়।
অ্যালেক্স বি

1

আপনি কোন গাছের কথা বলছেন? আছে স্ব-মিট সেখানে আউট গাছ। ভারসাম্য বজায় রাখার জন্য তাদের গাছটি পুনর্বিন্যাস করতে হবে কিনা তা নির্ধারণ করার জন্য তাদের অ্যালগরিদমগুলি পরীক্ষা করুন।


1

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

আপনি সর্বোচ্চ এবং সর্বনিম্ন উভয় সেট হয়ে থাকলে এবং পার্থক্য> 1 থাকলে তাড়াতাড়ি ফিরে এসে এটিকে আরও দ্রুত তৈরি করতে পারেন।

public boolean isBalanced( Node root ) {
    int curDepth = 0, maxLeaf = 0, minLeaf = INT_MAX;
    if ( root == null ) return true;
    while ( root != null ) {
        if ( root.left == null || root.right == null ) {
            maxLeaf = max( maxLeaf, curDepth );
            minLeaf = min( minLeaf, curDepth );
        }
        if ( root.left != null ) {
            curDepth += 1;
            root = root.left;
        } else {
            Node last = root;
            while ( root != null
             && ( root.right == null || root.right == last ) ) {
                curDepth -= 1;
                last = root;
                root = root.parent;
            }
            if ( root != null ) {
                curDepth += 1;
                root = root.right;
            }
        }
    }
    return ( maxLeaf - minLeaf <= 1 );
}

1
একটি দুর্দান্ত প্রচেষ্টা কিন্তু এটি পরিষ্কারভাবে কাজ করে না। এক্স একটি নাল নোড হতে দিন। একটি নন-নাল গাছ নোডকে (বামমূল্যের অধিকার) হিসাবে চিহ্নিত করা যাক। গাছটি বিবেচনা করুন (x এ (x বি এক্স))। "রুট" চিরকালের জন্য এ, বি, এ, বি, এ, বি ... নোডগুলিতে নির্দেশ করে। আবার চেষ্টা করার দরকার? একটি ইঙ্গিত: এটি আসলে সহজ প্যারেন্ট পয়েন্টার ছাড়াই এটি
এরিক লিপার্ট

@ এরিক: ওফস, ফিক্সড (আমার মনে হয়) ঠিক আছে, আমি ও (গভীরতা) মেমরি ছাড়াই এটি করার চেষ্টা করছি, এবং যদি কাঠামোর প্যারেন্ট পয়েন্টার না থাকে (এটি প্রায়শই হয়), আপনার একটি স্ট্যাক ব্যবহার করা দরকার।
পোটোসওয়টার

সুতরাং আপনি আমাকে যা বলছেন তা কি আপনি ও (ডি) অস্থায়ী মেমরি বরাদ্দ এড়াতে প্যারেন্ট পয়েন্টারে স্থায়ী মেমরি ব্যবহার করবেন, যেখানে লগ এন <= ডি <= এন? এটি মিথ্যা অর্থনীতি বলে মনে হচ্ছে।
এরিক লিপার্ট

দুর্ভাগ্যক্রমে, যদিও আপনি ট্র্যাভারসাল দিয়ে সমস্যাটি স্থির করেছেন, এখানে আরও অনেক বড় সমস্যা রয়েছে। এটি কোনও গাছ ভারসাম্যযুক্ত কিনা তা পরীক্ষা করে না, গাছের সমস্ত স্তর একই স্তরের কাছাকাছি রয়েছে কিনা তা পরীক্ষা করে। এটি যে "ভারসাম্যপূর্ণ" সংজ্ঞা দিয়েছি তা নয়। গাছটি বিবেচনা করুন (((x x x) C x) B x) A x)। আপনার কোডটি প্রতিবেদন করে যে এটি "ভারসাম্যযুক্ত" যখন স্পষ্টতই সর্বাধিক ভারসাম্যহীন হয়। আবার চেষ্টা করার দরকার?
এরিক লিপার্ট

@ এরিক উত্তর ১: আপনি যদি ইতিমধ্যে অন্য কোনও কিছুর জন্য প্যারেন্ট পয়েন্টার ব্যবহার করেন তবে এটি কোনও মিথ্যা অর্থনীতি নয়। উত্তর 2: নিশ্চিত, কেন না। এটি ডিবাগ করার একটি উদ্ভট উপায় ... আমি
ভোর চারটায়

1
/* Returns true if Tree is balanced, i.e. if the difference between the longest path and the shortest path from the root to a leaf node is no more than than 1. This difference can be changed to any arbitrary positive number. */
boolean isBalanced(Node root) {
    if (longestPath(root) - shortestPath(root) > 1)
        return false;
    else
        return true;
}


int longestPath(Node root) {
    if (root == null);
        return 0;
    else {
        int leftPathLength = longestPath(root.left);
        int rightPathLength = longestPath(root.right);
        if (leftPathLength >= rightPathLength)
            return leftPathLength + 1;
        else
            return rightPathLength + 1;
    }
}

int shortestPath(Node root) {
    if (root == null);
        return 0;
    else {
        int leftPathLength = shortestPath(root.left);
        int rightPathLength = shortestPath(root.right);
        if (leftPathLength <= rightPathLength)
            return leftPathLength + 1;
        else
            return rightPathLength + 1;
    }
}

1
আপনার কোডের নমুনায় আপনার উত্তর এবং / অথবা মন্তব্যগুলিতে কিছু বর্ণনা যুক্ত করা উচিত।
ব্র্যাড ক্যাম্পবেল

1
class Node {
    int data;
    Node left;
    Node right;

    // assign variable with constructor
    public Node(int data) {
        this.data = data;
    }
}

public class BinaryTree {

    Node root;

    // get max depth
    public static int maxDepth(Node node) {
        if (node == null)
            return 0;

        return 1 + Math.max(maxDepth(node.left), maxDepth(node.right));
    }

    // get min depth
    public static int minDepth(Node node) {
        if (node == null)
            return 0;

        return 1 + Math.min(minDepth(node.left), minDepth(node.right));
    }

    // return max-min<=1 to check if tree balanced
    public boolean isBalanced(Node node) {

        if (Math.abs(maxDepth(node) - minDepth(node)) <= 1)
            return true;

        return false;
    }

    public static void main(String... strings) {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);


        if (tree.isBalanced(tree.root))
            System.out.println("Tree is balanced");
        else
            System.out.println("Tree is not balanced");
    }
}

0

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

int heightBalanced(node *root){
    int i = 1;
    heightBalancedRecursive(root, &i);
    return i; 
} 

int heightBalancedRecursive(node *root, int *i){

    int lb = 0, rb = 0;

    if(!root || ! *i)  // if node is null or a subtree is not height balanced
           return 0;  

    lb = heightBalancedRecursive(root -> left,i);

    if (!*i)         // subtree is not balanced. Skip traversing the tree anymore
        return 0;

    rb = heightBalancedRecursive(root -> right,i)

    if (abs(lb - rb) > 1)  // not balanced. Make i zero.
        *i = 0;

    return ( lb > rb ? lb +1 : rb + 1); // return the current height of the subtree
}

0
public int height(Node node){
    if(node==null)return 0;
    else{
        int l=height(node.leftChild);
        int r=height(node.rightChild);
       return(l>r?l+1:r+1);

}}
public boolean balanced(Node n){

    int l= height(n.leftChild);
    int r= height(n.rightChild);

    System.out.println(l + " " +r);
    if(Math.abs(l-r)>1)
        return false;
    else 
        return true;
    }

0

একটি খালি গাছ উচ্চতা-ভারসাম্যযুক্ত। একটি খালি খালি বাইনারি গাছ টি সুষম হয় যদি:

1) টি এর বাম সাবট্রি সুষম হয়

2) টি এর ডান সাবট্রি সুষম হয়

3) বাম সাবট্রি এবং ডান সাবট্রির উচ্চতার মধ্যে পার্থক্য 1 এর বেশি নয়।

/* program to check if a tree is height-balanced or not */
#include<stdio.h>
#include<stdlib.h>
#define bool int

/* A binary tree node has data, pointer to left child
   and a pointer to right child */
struct node
{
  int data;
  struct node* left;
  struct node* right;
};

/* The function returns true if root is balanced else false
   The second parameter is to store the height of tree.  
   Initially, we need to pass a pointer to a location with value 
   as 0. We can also write a wrapper over this function */
bool isBalanced(struct node *root, int* height)
{
  /* lh --> Height of left subtree 
     rh --> Height of right subtree */   
  int lh = 0, rh = 0;  

  /* l will be true if left subtree is balanced 
    and r will be true if right subtree is balanced */
  int l = 0, r = 0;

  if(root == NULL)
  {
    *height = 0;
     return 1;
  }

  /* Get the heights of left and right subtrees in lh and rh 
    And store the returned values in l and r */   
  l = isBalanced(root->left, &lh);
  r = isBalanced(root->right,&rh);

  /* Height of current node is max of heights of left and 
     right subtrees plus 1*/   
  *height = (lh > rh? lh: rh) + 1;

  /* If difference between heights of left and right 
     subtrees is more than 2 then this node is not balanced
     so return 0 */
  if((lh - rh >= 2) || (rh - lh >= 2))
    return 0;

  /* If this node is balanced and left and right subtrees 
    are balanced then return true */
  else return l&&r;
}


/* UTILITY FUNCTIONS TO TEST isBalanced() FUNCTION */

/* Helper function that allocates a new node with the
   given data and NULL left and right pointers. */
struct node* newNode(int data)
{
    struct node* node = (struct node*)
                                malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;

    return(node);
}

int main()
{
  int height = 0;

  /* Constructed binary tree is
             1
           /   \
         2      3
       /  \    /
     4     5  6
    /
   7
  */   
  struct node *root = newNode(1);  
  root->left = newNode(2);
  root->right = newNode(3);
  root->left->left = newNode(4);
  root->left->right = newNode(5);
  root->right->left = newNode(6);
  root->left->left->left = newNode(7);

  if(isBalanced(root, &height))
    printf("Tree is balanced");
  else
    printf("Tree is not balanced");    

  getchar();
  return 0;
}

সময় জটিলতা: ও (এন)


0

বিশেষ করে বিশাল গাছগুলিতে আরও ভাল পারফরম্যান্স রাখতে আপনি প্রতিটি নোডে উচ্চতা বাঁচাতে পারেন তাই এটি স্থান বনামের কার্য সম্পাদনের বাইরে:

class Node {
    Node left;
    Node right;
    int value;
    int height;
}

সংযোজন বাস্তবায়ন এবং মুছে ফেলার জন্য একই উদাহরণ

void addNode(Node root,int v)
{    int height =0;
     while(root != null)
     {
         // Since we are adding new node so the height 
         // will increase by one in each node we will pass by
         root.height += 1;
         height++;
         else if(v > root.value){
            root = root.left();
            }
         else{
         root = root.right();
         }

     }

         height++;
         Node n = new Node(v , height);
         root = n;         
}
int treeMaxHeight(Node root)
{
 return Math.Max(root.left.height,root.right.height);
}

int treeMinHeight(Node root)
{
 return Math.Min(root.left.height,root.right.height);

}

Boolean isNodeBlanced(Node root)
{
   if (treeMaxHeight(root) - treeMinHeight(root) > 2)
       return false;

  return true;
}

Boolean isTreeBlanced (Node root)
{
    if(root == null || isTreeBalanced(root.left) && isTreeBalanced(root.right) && isNodeBlanced(root))
    return true;

  return false;

}

-1
    static boolean isBalanced(Node root) {
    //check in the depth of left and right subtree
    int diff = depth(root.getLeft()) - depth(root.getRight());
    if (diff < 0) {
        diff = diff * -1;
    }
    if (diff > 1) {
        return false;
    }
    //go to child nodes
    else {
        if (root.getLeft() == null && root.getRight() == null) {
            return true;
        } else if (root.getLeft() == null) {
            if (depth(root.getRight()) > 1) {
                return false;
            } else {
                return true;
            }
        } else if (root.getRight() == null) {
            if (depth(root.getLeft()) > 1) {
                return false;
            } else {
                return true;
            }
        } else if (root.getLeft() != null && root.getRight() != null && isBalanced(root.getLeft()) && isBalanced(root.getRight())) {
            return true;
        } else {
            return false;
        }
    }
}

-2

এই কাজ করবে না?

return ( ( Math.abs( size( root.left ) - size( root.right ) ) < 2 );

যে কোনও ভারসাম্যহীন গাছ সর্বদা এটি ব্যর্থ হবে।


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