Bir BST içinde K daha küçük en büyük elemanı bulmak için

oy
17

İkili arama ağacı ve bir tamsayı K göz önüne alındığında, ben az K. daha büyük elemanı bulmak istiyoruz

Aşağıdaki ağacında,

for K = 13, result = 12
for K = 10, result = 8
for K = 1 (or) 2, result = -1

      10

  5       12

2   8   11  14

Aşağıda mantığı çalıştı. Ama bunu yapmak için daha iyi bir yolu var mı?

int findNum(node* node, int K)
{
        if(node == NULL)
        {
                return -1;
        }
        else if(K <= node->data)
        {
                return findNum(node->left,K);
        }
        else if(K > node->data)
        {
                int t = findNum(node->right,K);
                return t > node->data ? t : node->data;
        }

        return -1;
}
Oluştur 13/06/2011 saat 19:22
kaynak kullanıcı
Diğer dillerde...                            


5 cevaplar

oy
1

Ben senin, yerel uygulanmasında kodu ile yürümek düşündürmektedir UPPER_BOUND :: seti rehberlik için. Bu tam sorunun çözümü, ama çok yakın değil.

Gerçek hayatta Genelde, bu sorunların en Kendi kod çözülmesi gerekmez. STL sizin için birçok ortak görevleri yapabilirsiniz. Bu, tabii ki dolayısıyla testi bunları çözmek için bilmek yararlıdır.

Cevap 13/06/2011 saat 19:29
kaynak kullanıcı

oy
3

Ben standart kütüphane olanaklarını kullanarak inanıyoruz. Böylece, benim çözüm kullanır std::set. :-)

int largest_num_smaller_than(std::set<int> const& set, int num)
{
    std::set<int>::const_iterator lb(set.lower_bound(num));
    return lb == set.begin() ? -1 : *--lb;
}
Cevap 13/06/2011 saat 19:33
kaynak kullanıcı

oy
19

Bu en az O (log n), 's. Ancak, ve yığın taşması olasılığını ortadan kaldırmak (tada!), Kuyruk Özyinelemeyi ortadan kaldırarak bir döngü içine bu çevirerek (bu görüşmeciler umurumda ana şey gibi görünüyor olan) verimliliğini artırabilir. Ağaç negatif sayılar içeriyorsa demek istiyorsan Ayrıca, kodu ... çalışmıyor negatif olmayan tamsayılar, bunu söylemek gerekir, ancak görüşmeyi sadece desem "tamsayılar" o zaman biraz farklı kod ve farklı bir API gerekir. (Aynı işlevi imza tutmak ancak başarısızlık üzerine -1 yerine K geri dönebilirler.)

BTW, bu bir ukalasın veya noktayı eksik veya nasıl çözüleceğini bilmiyorum çoğu anketör söylerdim bir kütüphane işlevini çağırarak uygulamadan bir görüşme soru, çünkü. böyle şeylere uğraşmayın etrafında yap, sadece sen görüşmeyi istediğini bildiklerini üzerinde çalışıyor olsun.

İşte bir uygulamasıdır:

// Return the greatest int < K in tree, or K if none.
int findNum (Node* tree, int K)
{
    int val = K;

    while( tree )
        if( tree->data >= K )
            tree = tree->left;
        else{
            val = tree->data; 
            tree = tree->right;
        }

    return val;
}
Cevap 13/06/2011 saat 20:25
kaynak kullanıcı

oy
5

Burada fikir sağ ağaca geçmek bundan sonra son düğümü kayıt olduğunu düşünüyorum. Bu nedenle, kodu (güncellendi) olacak

int findNum (Node *node, int K)
{
    Node* last_right_move = NULL;

    while (node)
    {
        if (K<=node->data)
            node = node->left;
        else
        {
            last_right_move = node;
            node = node->right;
        }
    }

    if (last_right_move)
        return last_right_move->data;
    else
        return NOT_FOUND;  // defined previously. (-1 may conflict with negative number)
}
Cevap 14/06/2011 saat 03:06
kaynak kullanıcı

oy
1

Ne ilk cevabı burada söyledim ve bu O (n günlük) daha iyi alamıyorum neden arkasındaki mantık olduğunu. Bu BST-arama / almak çağırarak oldukça yakın olan K. daha az en çok sayıda arıyoruz.

Orijinal algoritma oldukça iyi görünüyor olsa da, bu hızlı olacak:

    int findNum (node root, int K) {
        if(root == null) return -1;

        if(K > root.val) { 
           if(root.right != null) return findNum(root.right, K);               
           else return root.val; 
        }

        return findNum(root.left, K); //look in left subtree

    }
Cevap 27/07/2011 saat 11:11
kaynak kullanıcı

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