İkili arama ağaçlarının tanımında yinelenen anahtarlara izin veriliyor mu?


139

İkili bir arama ağacının tanımını bulmaya çalışıyorum ve her yerde farklı tanımlar bulmaya devam ediyorum.

Bazıları, herhangi bir alt ağaç için sol alt anahtarın kökten küçük veya ona eşit olduğunu söylüyor.

Bazıları, herhangi bir alt ağaç için doğru alt anahtarın kökten büyük veya ona eşit olduğunu söyler.

Ve eski kolej veri yapıları kitabım "her öğenin bir anahtarı ve iki öğenin aynı anahtarı olmadığını" söylüyor.

Bir bst'in evrensel bir tanımı var mı? Özellikle aynı anahtarın birden çok örneğine sahip ağaçlarla ne yapılacağı konusunda.

EDIT: Belki de belirsizdim, gördüğüm tanımlar

1) sol <= kök <sağ

2) sol <kök <= sağ

3) sol <kök <sağ, hiçbir yinelenen anahtar bulunmayacak şekilde.

Yanıtlar:


78

Birçok algoritma yinelemelerin hariç tutulacağını belirtir. Örneğin, MIT Algoritmaları kitabındaki örnek algoritmalar genellikle kopyaları olmayan örnekler sunar. Kopyaları uygulamak (düğümde bir liste olarak veya belirli bir yönde) oldukça önemsizdir.

(Gördüğüm) çoğu sol çocukları <= ve sağ çocukları> olarak belirtir. Pratik olarak, sağ veya sol çocukların kök düğüme eşit olmasına izin veren bir BST, yinelenen düğümlere izin verilen bir aramayı bitirmek için ekstra hesaplama adımları gerektirecektir.

Düğümün bir tarafına '=' değeri eklemek, düğümü alt öğe olarak yerleştirmek için ağacın yeniden yazılmasını gerektirdiğinden veya düğüm genel olarak yerleştirildiğinden, yinelenenleri depolamak için düğümdeki bir listeyi kullanmak en iyisidir. -çocuk, aşağıda bir noktada, arama verimliliğinin bir kısmını ortadan kaldırır.

Hatırlamanız gerekir ki, sınıf örneklerinin çoğu konsepti tasvir etmek ve sunmak için basitleştirilmiştir. Gerçek dünyadaki birçok durumda çömelmeye değmezler. Ancak, "her öğenin bir anahtarı vardır ve hiçbir iki öğenin aynı anahtarı yoktur" ifadesi, öğe düğümündeki bir listenin kullanılmasıyla ihlal edilmez.

Veri yapıları kitabınızın söylediklerine bakın!

Düzenle:

İkili Arama Ağacının Evrensel Tanımı, bir veri yapısını iki yönden birinden geçirmeye dayanan bir anahtarın saklanmasını ve aranmasını içerir. Pragmatik anlamda, eğer değer <> ise, veri yapısını iki 'yönden' geçersiniz. Yani, bu anlamda, yinelenen değerler hiç mantıklı değil.

Bu, BSP veya ikili arama bölümünden farklıdır, ancak hepsi bu kadar farklı değildir. Arama algoritması 'seyahat' için iki yönden birine sahiptir ya da yapılır (başarılı ya da değil) Bu yüzden orijinal cevabımın 'evrensel tanım' kavramını ele almadığından özür dilerim, çünkü kopyalar gerçekten farklı konu (ikili aramanın bir parçası olarak değil, başarılı bir aramadan sonra uğraştığınız bir şey)


1
Düğümde liste kullanmanın dezavantajları nelerdir?
Pacerier

1
@Pacerier Sanırım bir liste tutmak yerine, her bir düğümde bir referans sayısını koruyabilir ve yineleme meydana geldiğinde sayıyı güncelleyebiliriz. Böyle bir algoritma arama ve depolamada çok daha kolay ve verimli olacaktır. Ayrıca, mevcut algoritmada yinelenenleri desteklemeyen minimum değişiklikler gerekir.
SimpleGuy

50

İkili arama ağacınız kırmızı siyah bir ağaçsa veya herhangi bir "ağaç döndürme" işlemi yapmak istiyorsanız, yinelenen düğümler sorunlara neden olur. Ağaç kuralınızın şu olduğunu düşünün:

sol <kök <= sağ

Şimdi kökü 5, sol çocuğu sıfır ve sağ çocuğu 5 olan basit bir ağaç düşünün. Kökte sol rotasyon yaparsanız, sol çocukta 5 ve sağ çocukla kökte 5 olur. sıfır olmak. Şimdi sol ağaçtaki bir şey köke eşittir, ancak yukarıdaki kuralınız sol <kök olarak kabul edildi.

Kırmızı / siyah ağaçlarımın neden zaman zaman düzensiz geçeceğini anlamaya çalışarak saatler geçirdim, sorun yukarıda tarif ettiğim şeydi. Umarım biri bunu okur ve gelecekte saatlerce hata ayıklamadan kurtarır!


18
Eşit düğümleriniz olduğunda döndürmeyin! Bir sonraki seviyeye geçin ve döndürün.
Zengin

2
Diğer çözümler ya ağaç kuralını değiştirmek ya left <= node <= rightda sadece bir değerin ilk ortaya çıkışından önce eklemektir.
paxdiablo

Bu pratikte hangi sorunlara neden olabilir? Bana sola doğru <= düğüm <= sağ ile tamam, o zaman tüm kırmızı-siyah ağaç işlemleri her şekilde çalışır.
Björn Lindqvist

39

Her üç tanım da kabul edilebilir ve doğrudur. Bir BST'nin farklı varyasyonlarını tanımlarlar.

Üniversite veri yapınızın kitabı, tanımının tek mümkün olmadığını açıklığa kavuşturmadı.

Elbette, kopyalara izin vermek karmaşıklık ekler. "Left <= root <right" tanımını kullanırsanız ve şöyle bir ağacınız varsa:

      3
    /   \
  2       4

daha sonra bu ağaca "3" yinelenen bir anahtar eklenmesi ile sonuçlanır:

      3
    /   \
  2       4
    \
     3

Kopyaların bitişik düzeylerde olmadığını unutmayın.

Bu, yukarıdaki gibi bir BST temsilindeki kopyalara izin verirken büyük bir sorundur: kopyalar herhangi bir sayıda düzeyle ayrılabilir, bu nedenle çoğaltmanın varlığını kontrol etmek sadece bir düğümün hemen alt öğelerini kontrol etmek kadar basit değildir.

Bu sorunu önleme seçeneği, kopyaları yapısal olarak (ayrı düğümler olarak) temsil etmemek, bunun yerine anahtarın oluşum sayısını sayan bir sayaç kullanmaktır. Önceki örnekte şöyle bir ağaç bulunur:

      3(1)
    /     \
  2(1)     4(1)

ve yinelenen "3" anahtarının yerleştirilmesinden sonra:

      3(2)
    /     \
  2(1)     4(1)

Bu, bazı ekstra bayt ve sayaç işlemleri pahasına arama, çıkarma ve yerleştirme işlemlerini basitleştirir.


Kullandığım ders kitabında bundan hiç bahsedilmediğine çok şaşırdım. Prof ya da bahsetmedi, ne de yinelenen anahtarlar bile bir sorun smh ...
Oloff Biermann

22

Bir BST'de, bir düğümün sol tarafına inen tüm değerler düğümün kendisinden daha küçüktür (veya daha sonra bakınız). Benzer şekilde, bir düğümün sağ tarafına inen tüm değerler düğüm değerinden (a) büyük (veya ona eşit ) .

Bazı BST'ler yinelenen değerlere izin vermeyi seçebilir, dolayısıyla yukarıdaki "veya buna eşit" niteleyicileri.

Aşağıdaki örnek açıklığa kavuşabilir:

            |
      +--- 14 ---+
      |          |
+--- 13    +--- 22 ---+
|          |          |
1         16    +--- 29 ---+
                |          |
               28         29

Bu, yinelemelere izin veren bir BST gösterir - bir değer bulmak için kök düğümden başlayıp arama değerinizin düğüm değerinden küçük veya büyük olmasına bağlı olarak sol veya sağ alt ağacın aşağısına inildiğini görebilirsiniz.

Bu, aşağıdaki gibi bir şeyle tekrar tekrar yapılabilir:

def hasVal (node, srchval):
    if node == NULL:
         return false
    if node.val == srchval:
        return true
    if node.val > srchval:
        return hasVal (node.left, srchval)
    return hasVal (node.right, srchval)

ve şununla çağırır:

foundIt = hasVal (rootNode, valToLookFor)

Aynı değerdeki diğer düğümler için değerinizi bulduğunuzda aramaya devam etmeniz gerekebileceğinden, kopyalar biraz karmaşıklık katar.


(a) Eğer olabilir dilek sağlanan bu yüzden size belirli bir anahtar için nasıl arama aslında sıralama onları ters yönde ayarlamalısınız. Bir BST'nin, artan veya azalan konuyla ilgili olmasa da yalnızca bazı sıralı düzenleri sürdürmesi gerekir.


Yinelenen durum için, doğru alt öğenin node.val == srchval: yan tümcesindeki geçerli düğümle aynı olup olmadığını kontrol edebilir ve eğer öyleyse sağa gidebilir misiniz?
bneil

9

Cormen, Leiserson, Rivest ve Stein'ın üçüncü algoritma olan "Algoritmalara giriş" kitabında, ikili bir arama ağacı (BST) açıkça kopyalara izin vermek olarak tanımlanmıştır . Bu, şekil 12.1 ve aşağıdaki şekillerde görülebilir (sayfa 287):

"İkili arama ağacında anahtarları daima ikili arama ağacı özelliğini tatmin şekilde saklanır: Let x. İkili arama ağacında bir düğüm olması halinde ysol alt ağaçtaki bir düğümdür xsonra, y:key <= x:key. Eğer ybir xo zaman sağ alt ağaçtaki bir düğüm y:key >= x:key. "

Ayrıca , sayfa 308'de kırmızı-siyah bir ağaç şöyle tanımlanır:

"Kırmızı-siyah ağaç, düğüm başına fazladan bir bit depolama alanına sahip ikili bir arama ağacıdır: rengi"

Bu nedenle, bu kitapta tanımlanan kırmızı-siyah ağaçlar kopyaları destekler.


4

Herhangi bir tanım geçerlidir. Uygulamanızda tutarlı olduğunuz sürece (her zaman sağa eşit düğümler koyun, her zaman sola koyun veya asla izin vermeyin) o zaman iyisiniz. Onlara izin vermemek en yaygın olanıdır, ancak izin verilirse ve sağa veya sola yerleştirilirse hala bir BST'dir.


1
yinelenen anahtarlar içeren bir veri kümeniz varsa, bu öğelerin tümü farklı bir yöntemle (bağlantılı liste, vb.) Ağaçtaki 1 düğümde saklanmalıdır. ağaç sadece benzersiz anahtarlar içermelidir.
nickf

1
Ayrıca wiki'den sağ alt ağacın kökten "büyük veya ona eşit" değerler içerdiğine dikkat edin. Dolayısıyla wiki tanımı kendiliğinden çelişkilidir.
SoapBox

1
+1: Farklı insanlar farklı tanımlar kullanır. Yeni bir BST uygularsanız, yinelenen girişler hakkında hangi varsayımları yaptığınızdan emin olduğunuzdan emin olmanız gerekir.
Bay Fooz

1
Kopyalara izin verirken fikir birliği (sol <= kök <= sağ) gibi görünüyor. Ancak bazı millet bir BST tanımı dups izin vermez. Ya da belki bazı insanlar bunu ek karmaşıklıktan kaçınmak için bu şekilde öğretir.
Tim Merrifield

1
yanlış! EITHER sol <= kök <sağ VEYA sol <kök <= sağ, VEYA sol> kök> = sağ VEYA sol> = kök> sağ
Mitch Wheat

3

Kırmızı-siyah ağaç uygulaması üzerinde çalışırken, kırmızı-siyah kesici uç döndürme ile, kısıtlamayı gevşetmeniz gerektiğini fark edene kadar, ağacı birden fazla anahtarla doğrulamakta sorun yaşıyordum

left <= root <= right

Baktığım belgelerin hiçbiri yinelenen anahtarlar için izin verilmediğinden ve bunu döndürmek için döndürme yöntemlerini yeniden yazmak istemediğimden, düğümlerimde birden fazla değere izin vermek için düğümlerimi değiştirmeye karar verdim ve ağaç.


2

Söylediğin bu üç şeyin hepsi doğru.

  • Anahtarlar benzersizdir
  • Solda bundan daha az tuş var
  • Sağ tarafta bundan daha büyük tuşlar var

Sanırım ağacınızı tersine çevirebilir ve daha küçük anahtarları sağa koyabilirsiniz, ancak gerçekten "sol" ve "sağ" kavramı sadece şudur: Gerçekten solu olmayan bir veri yapısı hakkında düşünmemize yardımcı olan görsel bir kavram ya da doğru, bu yüzden gerçekten önemli değil.


1

1.) sol <= kök <sağ

2.) sol <kök <= sağ

3.) sol <kök <sağ, hiçbir yinelenen anahtar bulunmayacak şekilde.

Gitmek ve algoritma kitaplarımı kazmak zorunda kalabilirim, ama başımın üstünden (3) kanonik form.

(1) veya (2) yalnızca yinelenen düğümlere izin vermeye başladığınızda ve yinelenen düğümleri ağacın kendisine (liste içeren düğüm yerine) koyduğunuzda ortaya çıkar.


Sol <= kök <= sağın neden ideal olmadığını açıklayabilir misiniz?
Helin Wang

@Paxdiablo tarafından kabul edilen cevaba bir göz atın - Yinelenen değerin var olabileceğini görebilirsiniz >=. İdeal gereksinimlerinize bağlıdır, ancak çok sayıda yinelenen değeriniz varsa ve yinelenenlerin yapıda var olmasına izin verirseniz, bstiniz doğrusal olabilir - yani O (n).
Robert Paulson

1

Yinelenen Anahtarlar • Aynı anahtarla birden fazla veri öğesi varsa ne olur? - Bu, kırmızı-siyah ağaçlarda hafif bir problem oluşturur. - Aynı anahtara sahip düğümlerin aynı anahtara sahip diğer düğümlerin her iki tarafına dağıtılması önemlidir. - Yani, tuşlar 50, 50, 50 sırasına gelirse, • ikinci 50'nin birincinin sağına, üçüncü 50'sinin de birincinin soluna gitmesini istiyorsunuz. • Aksi takdirde, ağaç dengesizleşir. • Bu, ekleme algoritmasındaki bir çeşit rastgele işlemle ele alınabilir. - Ancak, aynı tuşa sahip tüm öğelerin bulunması gerekirse arama işlemi daha karmaşık hale gelir. • Aynı anahtarla öğeleri yasadışı ilan etmek daha kolaydır. - Bu tartışmada kopyalara izin verilmediğini varsayacağız

Kişi, ağacın her düğümü için yinelenen anahtarlar içeren bir liste oluşturabilir ve verileri listede depolayabilir.


1

@Robert Paulson'un cevaplarına biraz daha bilgi eklemek istiyorum.

Düğümün anahtar ve veri içerdiğini varsayalım. Dolayısıyla, aynı anahtara sahip düğümler farklı veriler içerebilir.
(Dolayısıyla, arama aynı düğüme sahip tüm düğümleri bulmalıdır)

1) sol <= cur <sağ

2) sol <cur <= sağ

3) sol <= cur <= sağ

4) sol <cur <sağ && cur aynı tuşa sahip kardeş düğümler içerir .

5) sol <cur <sağ, böylece yinelenen anahtar yok.

1) & 2) eğriliği önlemek için ağacın dönme ile ilgili fonksiyonları yoksa iyi çalışır .
Ancak bu form AVL ağacı veya Kırmızı-Siyah ağacı ile çalışmaz , çünkü rotasyon prensibi kıracaktır. Search (), düğümü düğümü ile bulsa bile, yinelenen anahtarlı düğümlerin yaprak düğümüne doğru gitmelidir. Arama için zaman karmaşıklığı sağlama =

teta (logN)

3) rotasyonla ilgili fonksiyonlara sahip herhangi bir BST formuyla iyi çalışır.
Ancak arama O (n) 'yi alır ve BST'yi kullanma amacını mahveder.
Diyelim ki ağacımız aşağıdaki gibi, 3) müdür.

         12
       /    \
     10     20
    /  \    /
   9   11  12 
      /      \
    10       12

Bunu yaparsak (12) arama biz kökünde bulundu 12 bile tho Bu ağaçta, yinelenen anahtar için aramaya sol ve sağ çocuğu hem arama tutmalısınız.
Bu söylediğim gibi O (n) zaman alıyor.

4) benim kişisel favorim. Diyelim ki kardeş aynı tuşa sahip düğüm anlamına geliyor.
Yukarıdaki ağacın altına dönüşebiliriz.

         12 - 12 - 12
       /    \
10 - 10     20
    /  \    /
   9   11  12

Şimdi herhangi bir arama O (logN) alacaktır, çünkü yinelenen anahtar için çocukları geçmemiz gerekmiyor.
Ve bu prensip AVL veya RB ağacı ile de iyi çalışır .


0

Elemanları ilişki sipariş <= a, toplam sipariş bu nedenle ilişki dönüşlü olmalıdır, ancak genellikle ikili bir arama ağacı (diğer adıyla BST) kopyaları olmayan bir ağaçtır.

Aksi takdirde, kopyalar varsa, aynı silme işlevini iki veya daha fazla çalıştırmanız gerekir!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.