হাস্কেলের একটি গাছ বাইনারি অনুসন্ধানের গাছ কিনা তা সন্ধান করুন


10
  type BSTree a = BinaryTree a

  data BinaryTree a = Null | Node (BinaryTree a) a (BinaryTree a)
                      deriving Show

  flattenTree :: BinaryTree a -> [a]
  flattenTree  tree = case tree of
      Null -> []
      Node left val right -> (flattenTree left) ++ [val] ++ (flattenTree right)

  isBSTree :: (Ord a) => BinaryTree a -> Bool
  isBSTree btree = case btree of
      Null -> False
      tree -> (flattenTree tree) == sort (flattenTree tree)

আমি যা করতে চাই তা হল একটি প্রদত্ত বৃক্ষটি বাইনারি অনুসন্ধানের গাছ কিনা তা নির্ধারণের জন্য একটি ফাংশন লিখতে, আমার পদ্ধতিটি হল একটি তালিকাতে সমস্ত মানকে তালিকাভুক্ত করে এবং আমদানি করা Data.Listএবং তারপরে তালিকাটি সমান কিনা তা সন্ধান করে তবে এটি একটু জটিল। অন্যান্য মডিউল আমদানি না করে আমরা কি এটি করতে পারি?


আমি flattenTreeপ্রথমে সংজ্ঞায়িত করব না Falseযদি কোনও নোড সেই নোডে থাকা পুরো সাবট্রিটিকে অতিক্রম না করে অনুসন্ধান সম্পত্তি লঙ্ঘন করে আপনি তাড়াতাড়ি ফিরে আসতে পারেন।
চিপনার

@ চেপনার সমস্যাটি রয়েছে, সাথে sortনয় flattenTree, যা যথেষ্ট অলস।
নেস

হ্যাঁ, এটি অন্যান্য উত্তরগুলির কিছু দেখার পরে আমার কাছে এসেছিল।
চিপনার

উত্তর:


13

গাছটিকে চ্যাপ্টা না করে এটি করার একটি উপায়।

সংজ্ঞা থেকে, এখানে,

data BinaryTree a = Null | Node (BinaryTree a) a (BinaryTree a)
     deriving Show

আপনি দেখতে পাচ্ছেন যে গাছটিকে বাম থেকে ডান দিকে অগ্রসর করা, উপেক্ষা Nodeএবং প্রথম বন্ধনী আপনাকে Nullআর aএস এর একটি বিকল্প ক্রম দেয় । যে, প্রতি দুটি মানের মধ্যে একটি আছে Null

আমার পরিকল্পনাটি হ'ল যে প্রতিটি সাবট্রি উপযুক্ত প্রয়োজনীয়তাগুলি সন্তুষ্ট করে : আমরা প্রতিটিটি প্রয়োজনীয়তাগুলি পরিমার্জন করতে পারি Node, আমরা কোন মানগুলির মধ্যে রয়েছি তা মনে করে তারপরে সেগুলি পরীক্ষা করে Null। যেহেতু Nullপ্রতিটি ক্রমের মানগুলির মধ্যে একটির মধ্যে একটি রয়েছে, আমরা পরীক্ষা করে দেখেছি যে সমস্ত ক্রম (বাম থেকে ডানে) জোড়া হ্রাস-হ্রাসযুক্ত।

প্রয়োজনীয়তা কী? এটি গাছের মানগুলির উপর একটি আলগা নিম্ন এবং উপরের আবদ্ধ। বাম দিকের এবং ডানদিকের প্রান্তগুলি সহ প্রয়োজনীয়তা প্রকাশের জন্য, আমরা Botটম এবং Topউপাদানগুলির সাথে কোনও ক্রম বাড়িয়ে দিতে পারি , নিম্নরূপ:

data TopBot a = Bot | Val a | Top deriving (Show, Eq, Ord)

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

ordBetween :: Ord a => TopBot a -> TopBot a -> BinaryTree a -> Bool
  -- tighten the demanded bounds, left and right of any Node
ordBetween lo hi (Node l x r) = ordBetween lo (Val x) l && ordBetween (Val x) hi r
  -- check that the demanded bounds are in order when we reach Null
ordBetween lo hi Null         = lo <= hi

একটি বাইনারি অনুসন্ধান বৃক্ষ একটি গাছ অনুক্রমে এবং মধ্যে যে Botএবং Top

isBSTree :: Ord a => BinaryTree a -> Bool
isBSTree = ordBetween Bot Top

কম্পিউটিং প্রকৃত প্রতিটি সাবট্রি মধ্যে একস্ট্রিমাল মূল্যবোধ, তাদের বাহিরের দিকে সাড়া জাগানো, আপনি আরও তথ্য চেয়ে আপনার যা দরকার দেয়, এবং প্রান্ত যখােন বাম বা ডান subtree খালি মধ্যে fiddly হয়। বজায় রাখার এবং পরীক্ষণ প্রয়োজনীয়তা , তাদের চিন্তায় ঠেলাঠেলি, বরং আরো অভিন্ন নয়।


6

এখানে একটি ইঙ্গিত দেওয়া হয়েছে: সহায়ক ফাংশন করুন

isBSTree' :: (Ord a) => BinaryTree a -> BSTResult a

যেখানে BSTResult aহিসাবে সংজ্ঞায়িত করা হয়

data BSTResult a
   = NotBST             -- not a BST
   | EmptyBST           -- empty tree (hence a BST)
   | NonEmptyBST a a    -- nonempty BST with provided minimum and maximum

আপনার পুনরাবৃত্তির সাথে এগিয়ে যাওয়া, সংক্ষিপ্তকরণটি চালানোর জন্য সাবট্রির উপর ফলাফলগুলি কাজে লাগানো, বিশেষত সর্বনিম্ন এবং সর্বোচ্চ able

উদাহরণস্বরূপ, যদি আপনার tree = Node left 20 rightসাথে থাকে isBSTree' left = NonEmptyBST 1 14এবং থাকে isBSTree' right = NonEmptyBST 21 45তবে তা isBSTree' treeহওয়া উচিত NonEmptyBST 1 45

একই ক্ষেত্রে বাদে tree = Node left 24 right, আমাদের পরিবর্তে থাকা উচিত isBSTree' tree = NotBST

ফলাফলটি রূপান্তরিত Boolকরা তখন তুচ্ছ।


1
বা এর জন্য সুস্পষ্ট মনোয়েড সংজ্ঞায়িত করুন BSTResult aএবং এতে ভাঁজ করুন। :) (অথবা এটি আইনী মনয়েড না হলেও ....)
নেস উইল

(তবে এটি আইনী, যাইহোক, আমি মনে করি)
উইল নেস,

3

হ্যাঁ , আপনার তালিকাটি বাছাই করার দরকার নেই। প্রতিটি উপাদান পরবর্তী উপাদানগুলির চেয়ে কম বা সমান কিনা তা আপনি পরীক্ষা করতে পারেন। এটি আরও কার্যকর কারণ যেহেতু আমরা ও (এন) এ এটি করতে পারি , সেখানে বাছাই করা তালিকার সম্পূর্ণ মূল্যায়ন O (n লগ এন) নেয় ।

আমরা এইভাবে এটি পরীক্ষা করতে পারি:

ordered :: Ord a => [a] -> Bool
ordered [] = True
ordered xa@(_:xs) = and (zipWith (<=) xa xs)

সুতরাং আমরা বাইনারি গাছের সাথে বাইনারি অনুসন্ধানের গাছ কিনা তা পরীক্ষা করতে পারি:

isBSTree :: Ord a => BinaryTree a -> Bool
isBSTree = ordered . flattenTree

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


1

আমরা গাছের উপরে বাম থেকে ডানে এগিয়ে যেতে পারি:

isBSTtreeG :: Ord a => BinaryTree a -> Bool
isBSTtreeG t = gopher Nothing [Right t]
    where
    gopher  _   []                        =  True
    gopher  x   (Right Null:ts)           =  gopher x ts
    gopher  x   (Right (Node lt v rt):ts) =  gopher x (Right lt:Left v:Right rt:ts)
    gopher Nothing   (Left v:ts)          =  gopher (Just v) ts
    gopher (Just y)  (Left v:ts)          =  y <= v && gopher (Just v) ts

জন ম্যাকার্থিgopher দ্বারা অনুপ্রাণিত ।

সুস্পষ্ট পুশ-ডাউন তালিকাটি ধারাবাহিকতা-পাসিংয়ের সাথে মুছে ফেলা যায়,

isBSTtreeC :: Ord a => BinaryTree a -> Bool
isBSTtreeC t = gopher Nothing t (const True)
    where
    gopher  x   Null           g  =  g x 
    gopher  x   (Node lt v rt) g  =  gopher x lt (\case
                                       Nothing -> gopher (Just v) rt g
                                       Just y  -> y <= v && gopher (Just v) rt g)

কেবলমাত্র একটি, সবচেয়ে দূর-দূরবর্তী উপাদান বজায় রাখা যথেষ্ট।

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