Haskellの幅優先でバイナリツリー(BSTない)を構築

JDMukiibs:

私は最近、Haskellの使用を開始し、それはおそらくのためになり、短い間。ただ、より良い私はユニで取っていたクラスのための関数型プログラミングを理解するためにそれを使用するように要求されています。

今、私は現在、私がやろうとしています何で直面しています若干の問題があります。私は幅優先それを構築したいが、私は私の条件が台無しにしまったか、私の条件はまた、単に間違っていると思います。

だから、基本的に私はそれを与えた場合[“A1-Gate”, “North-Region”, “South-Region”, “Convention Center”, “Rectorate”, “Academic Building1”, “Academic Building2”][0.0, 0.5, 0.7, 0.3, 0.6, 1.2, 1.4, 1.2]、私のツリーは次のように出てくるはずです

ツリーレイアウト私が達成しようとしています

しかし、私のテストの実行結果は、私が期待したものではない(笑)です。だから、Haskellの中の余分なシャープな専門家は、おそらく私が間違ってやっているものを見つけるのに役立つ可能性があります。出力:

*Main> l1 = ["A1-Gate", "North-Region", "South-Region", "Convention Center", 
             "Rectorate", "Academic Building1", "Academic Building2"]
*Main> l3 = [0.0, 0.5, 0.7, 0.3, 0.6, 1.2, 1.4, 1.2]
*Main> parkingtree = createBinaryParkingTree l1 l3
*Main> parkingtree
Node "North-Region" 0.5 
   (Node "A1-Gate" 0.0 EmptyTree EmptyTree) 
   (Node "Convention Center" 0.3 
     (Node "South-Region" 0.7 EmptyTree EmptyTree) 
     (Node "Academic Building2" 1.4 
       (Node "Academic Building1" 1.2 EmptyTree EmptyTree) 
       (Node "Rectorate" 0.6 EmptyTree EmptyTree)))

A-1のゲートは、rootでなければなりませんが、それはとてもきれい条件を台無しに子供がいない児童なってしまいます。

私はいくつかのガイダンスを得ることができればそれが役立つだろう。以下は、私がこれまで書いてきたものです::

data Tree = EmptyTree | Node [Char] Float Tree Tree deriving (Show,Eq,Ord)

insertElement location cost EmptyTree = 
   Node location cost EmptyTree EmptyTree
insertElement newlocation newcost (Node location cost left right) = 
   if (left == EmptyTree && right == EmptyTree)
   then Node location cost (insertElement newlocation newcost EmptyTree) 
                           right
   else if (left == EmptyTree && right /= EmptyTree)
        then Node location cost (insertElement newlocation newcost EmptyTree) 
                                right
        else if (left /= EmptyTree && right == EmptyTree)
             then Node location cost left 
                                (insertElement newlocation newcost EmptyTree)
             else Node newlocation newcost EmptyTree
                                (Node location cost left right)

buildBPT [] = EmptyTree
--buildBPT (xs:[]) = insertElement (fst xs) (snd xs) (buildBPT [])
buildBPT (x:xs) = insertElement (fst x) (snd x) (buildBPT xs)

createBinaryParkingTree a b = buildBPT (zip a b)

提供される可能性があります任意の指導をいただき、ありがとうございます。はい私が見てきたいくつかの私は私の問題が異なっていると思いますが、あなたは、特定のポストは私が行くと、それを見てみることを喜んで役立つ明確な答えを持っていると思う場合、同様の質問。

ウィルネス:

ここだcorecursiveソリューション。

{-#  bft(Xs,T) :- bft(Xs, [T|R], R).   % if you don't read Prolog, see (*) 

     bft(     [],    Ns ,      []) :-  maplist( =(empty), Ns).
     bft( [X|Xs], [N|Ns], [L,R|Z]) :-  N = node(X,L,R), 
        bft( Xs,     Ns,       Z).
#-}

data Tree a = Empty | Node a (Tree a) (Tree a) deriving Show

bft :: [a] -> Tree a
bft xs = head nodes    -- Breadth First Tree
  where
  nodes = zipWith g (map Just xs ++ repeat Nothing)
                                 -- true length of Empty leaves: |xs| + 1
                    (pairs $ tail nodes)
  g (Just x) (lt,rt) = Node x lt rt
  g Nothing  _       = Empty
  pairs ~(a: ~(b:c)) = (a,b) : pairs c

nodesすべての幅優先列挙ですサブツリー結果ツリーの。ツリー自体は、トップサブツリー、すなわち、このリストの最初のです。私たちは、作成NodeそれぞれからSをx入力してxs、入力がなくなったとき、私たちは作成Empty秒。

そして、我々はすべてでカウントする必要はありませんでした。

テスト:

> bft [1..4]
Node 1 (Node 2 (Node 4 Empty Empty) Empty) (Node 3 Empty Empty)

> bft [1..10]
Node 1 
   (Node 2 
      (Node 4 
         (Node 8  Empty Empty) 
         (Node 9  Empty Empty)) 
      (Node 5 
         (Node 10 Empty Empty) 
         Empty)) 
   (Node 3 
      (Node 6 Empty Empty) 
      (Node 7 Empty Empty))

それがどのように動作します:キーがあるgのは、それが強制しないことを、怠惰ltさんもrtタプル構造を容易によって提供されている間、値をさん-独自の権利で非常に怠惰な- pairs両方とも同じようにしているので、まだ設定されていない変数への2番目と3番目の引数を務めたことPrologの擬似コード(*)で、gしかし、その後、次のためxにあるxsltとなりg結果

そして、それはだrtのターンなど、いつxs終わり、私たちはヒットNothing、秒gから値を引っ張って停止するpairs「完全の出力。だから、pairs上の進出を停止しnodesすぎ。


(*)のPrologの変数がされ、明示的に 設定されワンス:彼らはであることが許可されている未割り当て状態。Haskellのは(x:xs)プロローグのです[X | Xs]

擬似コード:キューを維持します。エンキュー「未割り当てのポインタ」。xxs:へのキューの現在の頭の中で{セットポインタ未割り当てのポインタです。エンキュー; エンキュー; }キューポップ。にキューに残っているすべてのポインタを設定しますキューの元の頭の中で木を見つけた、すなわち、元の最初の「未割り当てのポインタ」Node(x, lt, rt)ltrtltrtEmpty(または「空の箱」の代わりに「未割り当てポインタが」別のオプションです)。

このプロローグの「キュー」はもちろん、完全に永続的である:「ポップ」任意のデータ構造を変化させません。また、キューの元ヘッドへの未解決の参照を変更しない-それだけでキューに現在のポインタを進めます。だから、このすべてのキューイングをきっかけに残っているもの、であるBFS-列挙木自体のhead要素で構築されたツリーのノードのは、 -木がある 2人の子供が完全で下葉にインスタンス化してその最上位ノードは、時間が列挙が行われます。


アップデート: @dfeuerは非常に単純化を思い付いたバージョン(ポストの上部にコメント内の1つのこと)、それをすることができはるかに近いPrologの元にあることの非常に 明確で、より効率的なコードや議論とスタッフを探して彼のポスト簡単な使い方[]の代わりに、より効率的な無限ストリーム型のdfeuerの使用のdata IS a = a :+ IS aサブツリーキューのを、それがなり、

bftree :: [a] -> Tree a
bftree xs = t
    where
    t : q  =  go xs q
    go []       _              =  repeat Empty
    go (x:ys) ~(l : ~(r : q))  =  Node x l r : go ys q

      ---READ-- ----READ----      ---WRITE---

比較のため、ツリーの幅優先列挙の逆の動作であります

bflist :: Tree a -> [a]
bflist t = [x | Node x _ _ <- q]
    where
    q  =  t : go 1 q
    go 0  _                =          []
    go i (Empty      : q)  =          go (i-1) q
    go i (Node _ l r : q)  =  l : r : go (i+1) q

         -----READ------     --WRITE--

どのようにbftree仕事は:t : q幅優先順にツリーのサブツリーのリストです。特定の呼び出しgo (x:ys)の使用l及びr それらはその後の呼び出しによって定義されるgo他のいずれか、xさらに下ys、またはによってgo []常に戻りますEmpty結果はt、このリストには非常に最初のすなわちツリー自体ツリーの最上位ノード、です。

ツリーノードのこのリストは、作成の再帰呼び出しによってgo値の入力リストがどのと同じ速度でxs消費されるが、として消費されている入力go二回、各ノードが持っているため、その速度2つのノード。

これらの追加のノードは、このようとしても、定義されなければならないEmptyの葉。空の葉の実際の数はもっとあったよりも1になりますが、我々は、任意の必要性を満たすために彼らの無限のリストを作成するだけで必要とされているどのように多くの気にしてませんxs

これは実際にツリーノードが線形アレイで幅優先順に配置されているアレイバックアップツリーの数十年のコンピュータサイエンスで使用したものと同じ方式です。不思議なことには、このような設定で変換の両方がある無操作 -の唯一の私たちの解釈に同じデータがどのように我々はそれを使用して/と対話している、変更何それの私達の扱いです。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=383964&siteId=1