Verilen ikili ağacın İçin maksimum ikili arama alt ağacı bulmak

oy
13

Verilen ikili ağaç için de ikili arama ağacı büyük alt ağacı bulmak?

Örnek:

Giriş:

                   10
               /         \
             50           150
            /  \         /   \
          25    75     200    20
         / \   / \    /  \    / \
        15 35 65 30  120 135 155 250 

Çıktı:

                   50
                  /   \
                 25   75
                / \   /
               15 35  65
Oluştur 02/07/2010 saat 06:15
kaynak kullanıcı
Diğer dillerde...                            


7 cevaplar

oy
0

Bir IN-SİPARİŞ Traversal'i yaparsanız bir ikili arama ağacı size sıralanmış sonucu verecektir. Yani, tüm ikili ağaç için bir in-sipariş geçişi yapmak. En uzun sıralanmış dizisi senin büyük ikili arama alt ağaçtır.

  • (SAĞ, ZİYARET ZİYARETİ SOL, ZİYARETİ ROOT) bir elementlerin inorder geçişini yapın
  • Bunu yaparken, düğüm veri almak, önceki düğüm veri sonraki verilerin daha az olup olmadığı karşılaştırın. Eğer öyleyse, 1. Mağaza başlangıç ​​düğümü ile karşı artırır.
  • Karşılaştırma başarısız olduğunda, son düğümü depolamak ve 0 karşı yeniden
  • Daha sonra maksimum değeri olan hangi bulmak için bir dizi yapısında bu bilgileri (sayaç, başlangıç, bitiş) düğümü saklayın ve bu sana en uzun ikili arama alt ağacı verecek
Cevap 02/07/2010 saat 06:26
kaynak kullanıcı

oy
2

İlginç soru!

Benim daha önceki girişimi moronically yanlış!

İşte (umarım bu sefer düzeltmek) Başka bir girişimdir.

Ağacın bağlı olduğu varsayıyorum.

Ağacın her bir düğüm n için varsayalım, n, S soyundan bir dizi vardı n özelliğiyle o

  • S her üyesi x n , n den x özgü yol bir İkili arama ağacı (bu sadece bir yoldur, ama yine de bunu bir ağaç düşünebiliriz) 'dir.

  • X'in her soyundan y için, y n'den yolu TSİ olduğu şekilde, yS içinde n .

Düğümleri S kümesi n , size n en köklü büyük BST'yi verir.

Biz S oluşturabilirsiniz n ağaç üzerinde bir derinlik ilk arama yapıyor ve yol bilgilerine (geçerli düğüme kökünden yolu) geçen ve yol boyunca geriye tarafından yolundaki düğümlerin setleri güncelleyerek her düğüm için.

Biz bir düğüm ziyaret ettiğinizde, yolu yürümek ve yolun söz konusu segmentin şimdiye kadar yürüdü için BST mülkiyet memnun olup olmadığını kontrol edin. Eğer öyleyse, biz sadece yürüdü yolunun düğümün gelen kümesine geçerli düğümü ekleyin. Biz yolunu BST mülkiyet ihlal edildi an yürüyen durdurmak. Şimdiye kadar yürüdü yol bölümü bir TSİ her düğüm için, bir O (PATH_LENGTH) zaman, toplam işlem süresi için, O (1) bir zamanda yapılabilir olup olmadığının kontrol edilmesi.

Sonunda, her bir düğüm olarak karşılık gelen S olacaktır n doldurulur. Şimdi ağaca yürümek ve S büyük değere sahip düğümünü seçebilirsiniz n .

Bunun için geçen süre (en kötü durumda) düğüm derinliklerinin toplamı olduğu ve ortalama durumda O (nlogn) 'nin (bir bölüm 5.2.4 http://www.toves.org/books/ veri / ch05-ağaç / index.html en kötü durumda), ancak O (n ^ 2).

Belki setleri güncellemek için zeki bir yolu kötü durum sürenin azaltılmasını garanti edecek.

Sözde kod gibi bir şey olabilir:

static Tree void LargestBST(Tree t)
{
    LargestBST(t, new List<Pair>());
    // Walk the tree and return the largest subtree with max |S_n|.
}

static Tree LargestBST(Tree t, List<Pair> path)
{
    if (t == null) return;

    t.Set.Add(t.Value);

    int value = t.Value;
    int maxVal = value;
    int minVal = value;

    foreach (Pair p in path)
    {
        if (p.isRight)
        {
            if (minVal < p.node.Value)
            {
                break;
            }
        }

        if (!p.isRight)
        {
            if (maxVal > p.node.Value)
            {
                break;
            }
        }

        p.node.Set.Add(t.Value);

        if (p.node.Value <= minVal)
        {
            minVal = p.node.Value;
        }

        if (p.node.Value >= maxVal)
        {
            maxVal = p.node.Value;
        }
    }

    Pair pl = new Pair();
    pl.node = t;
    pl.isRight = false;

    path.Insert(0, pl);
    LargestBST(t.Left, path);

    path.RemoveAt(0);

    Pair pr = new Pair();
    pr.node = t;
    pr.isRight = true;

    path.Insert(0, pr);

    LargestBST(t.Right, path);

    path.RemoveAt(0);

}
Cevap 02/07/2010 saat 14:13
kaynak kullanıcı

oy
0
GetLargestSortedBinarySubtree(thisNode, ref OverallBestTree)
    if thisNode == null
        Return null
    LeftLargest = GetLargestSortedBinarySubtree(thisNode.LeftNode, ref OverallBestTree)
    RightLargest = GetLargestSortedBinarySubtree(thisNode.RightNode, ref OverallBestTree)
    if LeftLargest.Max < thisNode.Value & RightLargest.Min > thisNode.Value
        currentBestTree = new BinaryTree(LeftLargest, thisNode.Value, RightLargest)
    else if LeftLargest.Max < thisNode.Value
        currentBestTree = new BinaryTree(LeftLargest, thisNode.Value, null)
    else if RightLargest.Min > thisNode.Value
        currentBestTree = new BinaryTree(null, thisNode.Value, RightLargest)
    else
        currentBestTree = new BinaryTree(null, thisNode.Value, null)
    if (currentBestTree.Size > OverallBestTree.Size)
        OverallBestTree = currentBestTree
    return currentBestTree

BlueRaja belirttiği gibi, bu algoritma doğru değil.

Gerçekten çağrılmalıdır GetLargestSortedBinarySubtreeThatCanBeRecursivelyConstructedFromMaximalSortedSubtrees.

Cevap 02/07/2010 saat 19:46
kaynak kullanıcı

oy
3

Bir önceki algoritma (revizyonları bakınız) idi O(n^2)- biz bunu genelleme yapabiliriz O(n log n)gerçekleri olduğunu fark ile:

  1. B büyük BST köküdür ve varsa b.left.value < b.value, o zaman b.leftBST da (için aynıdır b.right.value ≥ b.value)
  2. b büyük BST köküdür ve BST de ise, a ve b arasındaki her düğüm BST içindedir.

Bu nedenle, eğer c, a ve b arasında, ve c b köklü BST içinde değildir, ya da a, (nedeniyle (2.)) . Bir düğüm herhangi bir atası tarafından köklü BST ise bu gerçeği kullanarak, kolayca belirleyebilir. Biz'(Biz onun atalarının listesiyle birlikte bizim fonksiyonu içine bir düğüm geçirerek yapacağım ve ilişkili dk / maxValues akım alt düğümü o atası büyük BST kök aslında eğer tatmin etmek olurdu ll Bu listeyi diyoruz ancestorList). Biz potansiyel-köklerinin tüm koleksiyonu saklamak edeceğizoverallRootsList

şöyle takımından potentialRoot denilen bir yapı tanımlayalım:

Her potentialRoot aşağıdaki değerleri içerir:
* düğüm : Biz BST köküne için düşünen düğüm
* MINVALUE ve MAXVALUE : Başka bir düğüm arasında olmalıdır aralık düğüm tarafından köklü BST parçası olmak (her düğüm için farklı)
* subnodes : düğüm tarafından köklü büyük BST düğümlerin kalanı listesi

Sözde kodu şöyle (belirtilen tüm listeler potentialRoots listeleridir unutmayın) :

FindLargestBST(node, ancestorList):
    leftList, rightList = empty lists
    for each potentialRoot in ancestorList:
        if potentialRoot.minValue < node.Value ≤ potentialRoot.maxValue:
            add node to potentialRoot.subNodes (due to (1.))
            (note that the following copies contain references, not copies, of subNodes)
            add copy of potentialRoot to leftList, setting maxValue = node.Value
            add copy of potentialRoot to rightList, setting minValue = node.Value

    add the potentialRoot (node, -∞, +∞) to leftList, rightList, and overallRootsList
    FindLargestBST(node.left, leftList)
    FindLargestBST(node.right, rightList)

Sonunda overallRootsListbir listesi olacak npotentialRoots, alt düğümler bir liste ile her. Büyük subnodes listesiyle biri sizin BST olduğunu.

Olduğundan <treeHeight değerlerin ancestorListsonra, algoritma çalışır (ağaç dengeli olduğunu varsayarak),O(n log n)

Cevap 02/07/2010 saat 20:21
kaynak kullanıcı

oy
0
root(Tree L A R) = A

MaxBST(NULL) = (true, 0, NULL)
MaxBST(Tree L A R as T) = 
  let
    # Look at both children
    (L_is_BST, L_size, L_sub) = MaxBST(L)
    (R_is_BST, R_size, R_sub) = MaxBST(R)
  in
  # If they're both good, then this node might be good too
  if L_is_BST and R_is_BST and (L == NULL or root(L) < A) and (R == NULL or A < root(R))
  then (true, 1 + L_size + R_size, T)
  else
       # This node is no good, so give back the best our children had to offer
       (false, max(L_size, R_size), if L_size > R_size then L_sub else R_sub)

, Tam olarak bir kez, her ağaç düğümü bakar, böylece O (K) çalışır.

Düzenleme: Crud, bu bir alt ağacının bazı kısımlarını dışarıda bırakın ki dikkate almaz. Ben alt ağacı okuduğumda "Bazı düğümde köklü tüm ağaç" üstlendi. Daha sonra bu sorunu gidermek için geri gelebilir.

Cevap 03/07/2010 saat 01:15
kaynak kullanıcı

oy
4

Bu yanıt, daha önce, bir O bağlantı / kesme ağaçlarda dayalı bir algoritmayı (n log) ihtiva etmiştir. İşte basit O (n) çözüm.

Çekirdek bir düğüm kabul eden bir işlemdir, sol çocuk kökü benzersiz bir maksimum BSST, benzersiz bir maksimum BSST bu BSSTs sol ve sağdan en elemanlara sağ çocuğa dayalıdır ve işaretçiler. Bu girdileri (sürekli veri yapıları ile önlenebilir) yok eder ve minimum ve maksimum elemanları ile birlikte, belirli düğüm kökü benzersiz bir maksimum BSST oluşturur. Tüm BSST düğümleri soyundan sayısı not eklenmiş. Daha önce olduğu gibi, bu prosedür bir sıralama sonrası geçişine gelen defalarca denir. alt ağacı kurtarmak için büyük BSST kök hatırlamak; ince elekten sadece basit geçişi gerektirir.

Ben sol BSST sadece tedavi edeceğiz; Sağ simetriktir. Sol BSST kök yeni kökü büyükse, o zaman tüm alt ağaç kaldırılır ve yeni kök şimdi en soldaki edilir. Aksi halde, eski en soldaki düğüm hala en soldaki edilir. Sol BSST en sağ düğümden başlayan ve yukarı doğru hareket eden, köküne eşit veya daha az olan birinci düğüm bulmak. Onun sağ çocuk çıkarılmalıdır; Şimdi BST mülkiyet çalışmaları nedeniyle dikkat başka düğümleri gitmek gerekir! Silme yansıtacak şekilde sayar güncelleyerek, sol BSST köküne devam edin.

Bu, O nedenle, (n) döngü rağmen, orijinal ağaçtaki her kenar esas olarak sadece bir kere geçtiği olmasıdır.


DÜZENLEME: topluca, geçilen yollar sol omurga ve sağ omurga hariç BST maksimal doğrusal yolları vardır. Örneğin, girdi üzerinde

              H
             / \
            /   \
           /     \
          /       \
         /         \
        /           \
       /             \
      D               L
     / \             / \
    /   \           /   \
   /     \         /     \
  B       F       J       N
 / \     / \     / \     / \
A   C   E   G   I   K   M   O

burada her kenar geçilen olduğu yinelemeli aramalar:

              H
             / \
            /   \
           /     \
          /       \
         /         \
        /           \
       /             \
      D               L
     / h             h \
    /   h           h   \
   /     h         h     \
  B       F       J       N
 / d     d h     h l     l \
A   C   E   G   I   K   M   O
Cevap 03/07/2010 saat 17:46
kaynak kullanıcı

oy
1

Bir ikili ağaç EN BÜYÜK ikili arama ağacı:

Bu sorunu ele iki yolu vardır,

ı) büyük BST) bir düğüm itibaren tüm çocuklar BST koşulunu karşılamak gerekmez (uyarılmış değil

ii) büyük BST), bir düğümden, tüm çocuk TSİ koşulu karşılayacak (indüklenen

Biz burada (Not Bağlı) büyük BST hakkında tartışacağız. Biz bu çözmek için aşağıdan yukarıya yaklaşımı (Mesaj sipariş geçişi) takip edecektir.

a) yaprak düğümü Erişim

b) yapraktan bir ağaç düğüm () içinde, aşağıdaki alanlar içeren bir TreeNodeHelper nesne döndürür.

public static class TreeNodeHelper {
        TreeNode node;
        int nodes;
        Integer maxValue;
        Integer minValue;
        boolean isBST;


        public TreeNodeHelper() {}

        public TreeNodeHelper(TreeNode node, int nodes, Integer maxValue, Integer minValue, boolean isBST) {
            this.node = node;
            this.nodes = nodes;
            this.maxValue = maxValue;
            this.minValue = minValue;
            this.isBST = isBST;
        }      
    }

c) İlk yaprak düğümünden, düğümler = 1, MINVALUE = MaxValue = node.data isBST = doğru. o BST koşulunu karşılayan Ve eğer daha da düğümler artırılacak sayısı.

d) Bu yardımı ile, geçerli düğüme BST durumunu kontrol edecektir. Ve biz köküne kadar aynı tekrar edecektir.

e) her bir düğümden iki nesne döndürülür. Geçen maksimum BST ve güncel BST tatmin edici düğümler için başka biri için bir tane. Yani (sağ alt ağaç için 2 sol alt ağaç ve 2) (yaprak üzerinde) her bir düğüm (2 + 2) = 4 ila nesneler karşılaştırılacak ve iki iade edilecektir.

f) kökünden nihai maksimum düğüm nesnesi büyük BST olacak

SORUN:

Bu yaklaşımda bir sorun vardır. Bu yaklaşımı izlerken bir alt ağaç geçerli düğüme BST koşulunu sağlayan değilse, biz sadece alt ağacı göz ardı edemeyiz (hatta düğümlerin az sayıda vardır). Örneğin

 55
  \
   75
  /  \
 27  89
    /  \
   26  95
      /  \
     23  105
         /  \
        20  110

yaprak düğümleri (20.110) nesneleri düğüm (105) ile test edilecek itibaren, koşulu karşılayan. o düğüm ulaştığında Ama (95) yaprak düğüm (20) BST koşulunu tatmin etmiyor. Bu çözeltiye, (ma kaynaklı) BST için beri koşulu karşılayan düğümü (105) ve düğümü (110), göz ardı edilmemelidir. Yani düğüm (95) biz BST durumunu test tekrar sarfınazar ve bu düğümleri (105, 110) yakalamak zorundayız.

Bu uygulama için komple kod bu bağlantıyı mevcuttur

https://github.com/dineshappavoo/Implementation/tree/master/LARGEST_BST_IN_BT_NOT_INDUCED_VER1.0

Cevap 27/03/2014 saat 00:48
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more