최적의 방식으로 이진 검색 트리에서 k 번째로 작은 요소 찾기


112

정적 / 전역 변수를 사용하지 않고 이진 검색 트리에서 k 번째로 작은 요소를 찾아야합니다. 효율적으로 달성하는 방법은 무엇입니까? 내가 생각하는 해결책은 O (n)에서 작업을 수행하는 것인데, 전체 트리를 순회 할 계획이므로 최악의 경우입니다. 그러나 나는 여기서 BST 속성을 사용하지 않는다고 느낍니다. 내 가정적인 솔루션이 정확합니까 아니면 더 나은 솔루션이 있습니까?


7
나무가 균형을 이루고 있습니까?
kennytm 2010

아닙니다. 하지만 균형 잡힌다면 최적의 방법이 있습니까?
bragboy

1
"주문 통계"를 검색하면 필요한 것을 찾을 수 있습니다.
RAL

나는 아래 답변의 대부분을 느낍니다. 정확한 것은 일종의 전역 변수를 사용하고 있다는 점에서 속임수입니다 (정수에 대한 참조이든 감소하고 반환되는 변수이든). 그 절대적으로 아무 것도 허용하지 않으면, 나는 어떤 참조가 전달되지 않고 재귀를 사용할 수 있습니다.
헨리 치우

답변:


170

다음은 아이디어의 개요입니다.

BST에서 노드의 왼쪽 하위 트리 T에는에 저장된 값보다 작은 요소 만 포함됩니다 T. 경우 k좌측 서브 트리 내의 요소의 수보다 작은 k최소 번째 요소는 좌측 서브 트리에 속해야한다. 그렇지 k않고 더 크면 k가장 작은 요소가 오른쪽 하위 트리에 있습니다.

BST를 확장하여 각 노드가 왼쪽 하위 트리에 요소 수를 저장하도록 할 수 있습니다 (주어진 노드의 왼쪽 하위 트리에 해당 노드가 포함되어 있다고 가정). 이 정보를 사용하면 왼쪽 하위 트리의 요소 수를 반복적으로 요청하여 트리를 탐색하여 왼쪽 또는 오른쪽 하위 트리로 재귀할지 여부를 결정하는 것이 간단합니다.

이제 노드 T에 있다고 가정합니다.

  1. 경우 (T의 서브 트리를 왼쪽) K == NUM_ELEMENTS , 우리가 찾고있는 대답은 노드의 값입니다 T.
  2. 경우 K> NUM_ELEMENTS (T의 좌측 서브 트리)은 이들 요소도보다 작을 수 있기 때문에, 그때 분명 우리는 좌측 서브 트리를 무시해 k번째 최소. 따라서 문제를 k - num_elements(left subtree of T)오른쪽 하위 트리 에서 가장 작은 요소 를 찾는 것으로 줄 입니다.
  3. 경우 K <NUM_ELEMENTS (T의 왼쪽 하위 트리) , 그 다음 k우리가 찾는 문제를 줄일 수 있도록 일 최소의 왼쪽 서브 트리에 어딘가에 k왼쪽 하위 트리에서 일 가장 작은 요소.

복잡성 분석 :

이것은 균형이 잡힌 BST의 경우 최악의 경우 또는 임의의 BST의 경우 평균적으로 O(depth of node)시간 이 걸립니다 .O(log n)O(log n)

BST에는 O(n)스토리지 가 필요하며 O(n)요소 수에 대한 정보를 저장하려면 다른 스토리지 가 필요합니다 . 모든 BST 작업 O(depth of node)에는 시간이 걸리며 O(depth of node)노드의 삽입, 삭제 또는 회전을 위해 "요소 수"정보를 유지하는 데 추가 시간 이 걸립니다 . 따라서 왼쪽 하위 트리의 요소 수에 대한 정보를 저장하면 BST의 공간 및 시간 복잡성이 유지됩니다.


59
N 번째로 작은 항목을 찾으려면 왼쪽 하위 트리의 크기 만 저장하면됩니다. N 번째로 큰 항목을 찾으려면 오른쪽 하위 트리의 크기를 사용합니다. 사실, 당신은 그것을 덜 비싸게 만들 수 있습니다 : 루트에 트리의 전체 크기와 왼쪽 하위 트리의 크기를 저장하십시오. 오른쪽 하위 트리의 크기가 필요한 경우 전체 크기에서 왼쪽의 크기를 뺄 수 있습니다.
Jerry Coffin

37
이러한 증강 BST를 '주문 통계 트리'라고합니다.
Daniel

10
@Ivlad : 2 단계 : 루트 요소도 포함해야하므로 "k-num_elements"는 "k-num_elements -1"이어야한다고 생각합니다.
understack

1
@understack-루트가 하위 트리의 일부라고 가정하지 않습니다.
IVlad

16
트리가 "왼쪽 및 오른쪽 하위 트리의 요소 수"를 포함하는 필드를 포함하지 않는 경우 메서드는 BigO (n)가됩니다.이를 위해서는 각 노드에서 오른쪽 또는 왼쪽 하위 트리를 걸어야하기 때문입니다. 현재 노드의 k 인덱스를 계산합니다.
Robert S. Barnes

68

더 간단한 해결책은 inorder traversal을 수행하고 현재 인쇄 할 요소를 추적하는 것입니다 (인쇄하지 않음). k에 도달하면 요소를 인쇄하고 나머지 트리 순회를 건너 뜁니다.

void findK(Node* p, int* k) {
  if(!p || k < 0) return;
  findK(p->left, k);
  --k;
  if(k == 0) { 
    print p->data;
    return;  
  } 
  findK(p->right, k); 
}

1
+1 : 아이디어는 올바른 방향이지만 일부 느슨한 끝을 조여야 할 수도 있습니다. stackoverflow.com/a/23069077/278326
Arun

1
BST가 이미 주문되었으므로 순회로 충분해야합니다.
Merlin

3
n이이 트리의 총 노드 수에 가까우면 알고리즘이 완료되는 데 O (n) 시간이 걸리며 선택한 답변에 적합하지 않습니다 .-O (log n)
Spark8006

13
public int ReturnKthSmallestElement1(int k)
    {
        Node node = Root;

        int count = k;

        int sizeOfLeftSubtree = 0;

        while(node != null)
        {

            sizeOfLeftSubtree = node.SizeOfLeftSubtree();

            if (sizeOfLeftSubtree + 1 == count)
                return node.Value;
            else if (sizeOfLeftSubtree < count)
            {
                node = node.Right;
                count -= sizeOfLeftSubtree+1;
            }
            else
            {
                node = node.Left;
            }
        }

        return -1;
    }

이것은 위의 알고리즘을 기반으로 한 C #의 구현입니다. 사람들이 더 잘 이해할 수 있도록 게시 할 것이라고 생각했습니다.

감사합니다 IVlad


11

더 간단한 해결책은 inorder traversal을 수행하고 카운터 k를 사용하여 현재 인쇄 될 요소를 추적하는 것입니다. k에 도달하면 요소를 인쇄합니다. 런타임은 O (n)입니다. 함수 반환 유형은 무효 일 수 없으며 각 재귀 호출 후에 업데이트 된 k 값을 반환해야합니다. 이에 대한 더 나은 솔루션은 각 노드에서 정렬 된 위치 값이있는 증강 BST입니다.

public static int kthSmallest (Node pivot, int k){
    if(pivot == null )
        return k;   
    k = kthSmallest(pivot.left, k);
    k--;
    if(k == 0){
        System.out.println(pivot.value);
    }
    k = kthSmallest(pivot.right, k);
    return k;
}

나는 당신의 솔루션이 증강 BST에 비해 공간 복잡성 측면에서 더 낫다고 생각합니다.
zach

k 번째로 작은 요소가 발견 된 후에도 검색이 중지되지 않습니다.
Vineeth Chitteti

10

// 재귀없이 자바 버전 추가

public static <T> void find(TreeNode<T> node, int num){
    Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();

    TreeNode<T> current = node;
    int tmp = num;

    while(stack.size() > 0 || current!=null){
        if(current!= null){
            stack.add(current);
            current = current.getLeft();
        }else{
            current = stack.pop();
            tmp--;

            if(tmp == 0){
                System.out.println(current.getValue());
                return;
            }

            current = current.getRight();
        }
    }
}

이 솔루션과 해당하는 재귀 솔루션을 좋아합니다. 솔직히이 질문에 대한 대부분의 답변은 읽기에는 너무 혼란 스럽거나 복잡합니다.
Henley Chiu

이 솔루션을 좋아합니다! 명확하고 훌륭합니다!
Rugal

이 솔루션은 '순서대로'트리를 탐색하고 노드를 방문한 후 카운터를 감소시켜 카운터가 0이되면 나중에 중지합니다. 최악의 경우는 O (n) 순서입니다. 아니, 그 최악의 경우 IVlad의 재귀 솔루션 @과 비교하여 가장 최적의는 O (로그 n)이 소요됩니다
조지 P.


4

평범한 이진 검색 트리가 주어지면 가장 작은 것부터 시작하여 올바른 노드를 찾기 위해 위로 이동하는 것입니다.

이 작업을 자주 수행하려는 경우 각 노드에 왼쪽 하위 트리에 몇 개의 노드가 있는지 나타내는 속성을 추가 할 수 있습니다. 이를 사용하여 트리를 올바른 노드로 직접 내려갈 수 있습니다.


4

카운터가있는 재귀 순서대로 걷기

Time Complexity: O( N ), N is the number of nodes
Space Complexity: O( 1 ), excluding the function call stack

이 아이디어는 @prasadvk 솔루션과 유사하지만 몇 가지 단점이 있으므로 (아래 참고 참조) 별도의 답변으로 게시합니다.

// Private Helper Macro
#define testAndReturn( k, counter, result )                         \
    do { if( (counter == k) && (result == -1) ) {                   \
        result = pn->key_;                                          \
        return;                                                     \
    } } while( 0 )

// Private Helper Function
static void findKthSmallest(
    BstNode const * pn, int const k, int & counter, int & result ) {

    if( ! pn ) return;

    findKthSmallest( pn->left_, k, counter, result );
    testAndReturn( k, counter, result );

    counter += 1;
    testAndReturn( k, counter, result );

    findKthSmallest( pn->right_, k, counter, result );
    testAndReturn( k, counter, result );
}

// Public API function
void findKthSmallest( Bst const * pt, int const k ) {
    int counter = 0;
    int result = -1;        // -1 := not found
    findKthSmallest( pt->root_, k, counter, result );
    printf("%d-th element: element = %d\n", k, result );
}

참고 (및 @prasadvk 솔루션과의 차이점) :

  1. if( counter == k )테스트는 (a) 왼쪽 하위 트리 뒤, (b) 루트 뒤, (c) 오른쪽 하위 트리 뒤의 위치 에서 필요합니다 . 이는 모든 위치 에 대해 즉, 위치 하는 하위 트리에 관계없이 k 번째 요소가 감지되도록하기위한 것 입니다.

  2. if( result == -1 )결과 요소 만 인쇄 되는지 확인하는 데 필요한 테스트입니다 . 그렇지 않으면 k 번째에서 가장 작은 요소부터 루트까지 모든 요소가 인쇄됩니다.


이 솔루션의 시간 복잡도는입니다 O(k + d). 여기서는 d트리의 최대 깊이입니다. 따라서 전역 변수를 사용 counter하지만이 질문에는 불법입니다.
Valentin Shergin 2014

안녕하세요 Arun, 예를 들어 설명해 주시겠습니까? 나는 이것이 특히 당신의 첫 번째 요점을 이해하지 못합니다.
Andy897

3

들어 하지 검색 트리를 균형, 그것은 소요 O (N)를 .

들면 균형 탐색 트리는 얻어 O (K + N 로그)을 최악의 경우이지만 단지 O (K)상각 의미.

모든 노드에 대한 추가 정수 보유 및 관리 : 하위 트리의 크기는 O (log n)를 제공합니다. 시간 복잡도를 제공합니다. 이러한 균형 잡힌 검색 트리를 일반적으로 RankTree라고합니다.

일반적으로 트리가 아닌 솔루션이 있습니다.

문안 인사.


1

이것은 잘 작동합니다 : status : 요소가 있는지 여부를 보유하는 배열입니다. k : 찾을 k 번째 요소입니다. count : 트리 순회 중에 순회 된 노드 수를 추적합니다.

int kth(struct tree* node, int* status, int k, int count)
{
    if (!node) return count;
    count = kth(node->lft, status, k, count);  
    if( status[1] ) return status[0];
    if (count == k) { 
        status[0] = node->val;
        status[1] = 1;
        return status[0];
    }
    count = kth(node->rgt, status, k, count+1);
    if( status[1] ) return status[0];
    return count;
}

1

이것이 문제에 대한 최적의 해결책은 아니지만 일부 사람들이 흥미로울 것이라고 생각하는 또 다른 잠재적 인 해결책입니다.

/**
 * Treat the bst as a sorted list in descending order and find the element 
 * in position k.
 *
 * Time complexity BigO ( n^2 )
 *
 * 2n + sum( 1 * n/2 + 2 * n/4 + ... ( 2^n-1) * n/n ) = 
 * 2n + sigma a=1 to n ( (2^(a-1)) * n / 2^a ) = 2n + n(n-1)/4
 *
 * @param t The root of the binary search tree.
 * @param k The position of the element to find.
 * @return The value of the element at position k.
 */
public static int kElement2( Node t, int k ) {
    int treeSize = sizeOfTree( t );

    return kElement2( t, k, treeSize, 0 ).intValue();
}

/**
 * Find the value at position k in the bst by doing an in-order traversal 
 * of the tree and mapping the ascending order index to the descending order 
 * index.
 *
 *
 * @param t Root of the bst to search in.
 * @param k Index of the element being searched for.
 * @param treeSize Size of the entire bst.
 * @param count The number of node already visited.
 * @return Either the value of the kth node, or Double.POSITIVE_INFINITY if 
 *         not found in this sub-tree.
 */
private static Double kElement2( Node t, int k, int treeSize, int count ) {
    // Double.POSITIVE_INFINITY is a marker value indicating that the kth 
    // element wasn't found in this sub-tree.
    if ( t == null )
        return Double.POSITIVE_INFINITY;

    Double kea = kElement2( t.getLeftSon(), k, treeSize, count );

    if ( kea != Double.POSITIVE_INFINITY )
        return kea;

    // The index of the current node.
    count += 1 + sizeOfTree( t.getLeftSon() );

    // Given any index from the ascending in order traversal of the bst, 
    // treeSize + 1 - index gives the
    // corresponding index in the descending order list.
    if ( ( treeSize + 1 - count ) == k )
        return (double)t.getNumber();

    return kElement2( t.getRightSon(), k, treeSize, count );
}

1

서명:

Node * find(Node* tree, int *n, int k);

전화 :

*n = 0;
kthNode = find(root, n, k);

정의:

Node * find ( Node * tree, int *n, int k)
{
   Node *temp = NULL;

   if (tree->left && *n<k)
      temp = find(tree->left, n, k);

   *n++;

   if(*n==k)
      temp = root;

   if (tree->right && *n<k)
      temp = find(tree->right, n, k);

   return temp;
}

1

여기 내 2 센트가 ...

int numBSTnodes(const Node* pNode){
     if(pNode == NULL) return 0;
     return (numBSTnodes(pNode->left)+numBSTnodes(pNode->right)+1);
}


//This function will find Kth smallest element
Node* findKthSmallestBSTelement(Node* root, int k){
     Node* pTrav = root;
     while(k > 0){
         int numNodes = numBSTnodes(pTrav->left);
         if(numNodes >= k){
              pTrav = pTrav->left;
         }
         else{
              //subtract left tree nodes and root count from 'k'
              k -= (numBSTnodes(pTrav->left) + 1);
              if(k == 0) return pTrav;
              pTrav = pTrav->right;
        }

        return NULL;
 }

0

이것은 내가 그래도 작동합니다. o (log n)에서 실행됩니다.

public static int FindkThSmallestElemet(Node root, int k)
    {
        int count = 0;
        Node current = root;

        while (current != null)
        {
            count++;
            current = current.left;
        }
        current = root;

        while (current != null)
        {
            if (count == k)
                return current.data;
            else
            {
                current = current.left;
                count--;
            }
        }

        return -1;


    } // end of function FindkThSmallestElemet

3
이 솔루션이 작동하지 않을 것이라고 생각합니다. K 번째 가장 작은 것이 트리 노드의 오른쪽 하위 트리에 있으면 어떻게 될까요?
Anil Vishnoi

0

단순히 순회 순회를 사용하고 방문한 요소를 스택으로 푸시 할 수 있습니다. 답을 얻기 위해 k 번 팝니다.

k 요소 이후에도 멈출 수 있습니다.


1
이것은 최적의 솔루션이 아닙니다
bragboy

0

완전한 BST 케이스에 대한 솔루션 :-

Node kSmallest(Node root, int k) {
  int i = root.size(); // 2^height - 1, single node is height = 1;
  Node result = root;
  while (i - 1 > k) {
    i = (i-1)/2;  // size of left subtree
    if (k < i) {
      result = result.left;
    } else {
      result = result.right;
      k -= i;
    }  
  }
  return i-1==k ? result: null;
}

0

Linux Kernel은 linux / lib / rbtree.c의 O (log n)에서 순위 기반 작업을 지원하는 우수한 증강 레드-블랙 트리 데이터 구조를 가지고 있습니다.

매우 조잡한 Java 포트는 http://code.google.com/p/refolding/source/browse/trunk/core/src/main/java/it/unibo/refolding/alg/RbTree.java 에서도 찾을 수 있습니다 . RbRoot.java 및 RbNode.java와 함께. n 번째 요소는 RbNode.nth (RbNode node, int n)을 호출하여 트리의 루트를 전달하여 얻을 수 있습니다.


0

다음 은 k 번째로 작은 요소 를 반환 하지만 k를 ref 인수로 전달해야하는 C # 의 간결한 버전입니다 (@prasadvk와 동일한 접근 방식).

Node FindSmall(Node root, ref int k)
{
    if (root == null || k < 1)
        return null;

    Node node = FindSmall(root.LeftChild, ref k);
    if (node != null)
        return node;

    if (--k == 0)
        return node ?? root;
    return FindSmall(root.RightChild, ref k);
}

가장 작은 노드 를 찾는 것은 O (log n) 이고, k 번째 노드로 이동하는 것은 O (k)이므로 O (k + log n)입니다.


Java 버전은 어떻습니까?
Henley Chiu


0

나는 더 나은 알고리즘을 찾을 수 없었습니다. 그래서 하나를 작성하기로 결정했습니다. :) 이것이 잘못된 경우 저를 수정하십시오.

class KthLargestBST{
protected static int findKthSmallest(BSTNode root,int k){//user calls this function
    int [] result=findKthSmallest(root,k,0);//I call another function inside
    return result[1];
}
private static int[] findKthSmallest(BSTNode root,int k,int count){//returns result[]2 array containing count in rval[0] and desired element in rval[1] position.
    if(root==null){
        int[]  i=new int[2];
        i[0]=-1;
        i[1]=-1;
        return i;
    }else{
        int rval[]=new int[2];
        int temp[]=new int[2];
        rval=findKthSmallest(root.leftChild,k,count);
        if(rval[0]!=-1){
            count=rval[0];
        }
        count++;
        if(count==k){
            rval[1]=root.data;
        }
        temp=findKthSmallest(root.rightChild,k,(count));
        if(temp[0]!=-1){
            count=temp[0];
        }
        if(temp[1]!=-1){
            rval[1]=temp[1];
        }
        rval[0]=count;
        return rval;
    }
}
public static void main(String args[]){
    BinarySearchTree bst=new BinarySearchTree();
    bst.insert(6);
    bst.insert(8);
    bst.insert(7);
    bst.insert(4);
    bst.insert(3);
    bst.insert(4);
    bst.insert(1);
    bst.insert(12);
    bst.insert(18);
    bst.insert(15);
    bst.insert(16);
    bst.inOrderTraversal();
    System.out.println();
    System.out.println(findKthSmallest(bst.root,11));
}

}


0

다음은 자바 코드입니다.

max (Node root, int k)-k 번째로 큰 값 찾기

min (Node root, int k) -가장 작은 k 번째 찾기

static int count(Node root){
    if(root == null)
        return 0;
    else
        return count(root.left) + count(root.right) +1;
}
static int max(Node root, int k) {
    if(root == null)
        return -1;
    int right= count(root.right);

    if(k == right+1)
        return root.data;
    else if(right < k)
        return max(root.left, k-right-1);
    else return max(root.right, k);
}

static int min(Node root, int k) {
    if (root==null)
        return -1;

    int left= count(root.left);
    if(k == left+1)
        return root.data;
    else if (left < k)
        return min(root.right, k-left-1);
    else
        return min(root.left, k);
}

0

이것도 작동합니다. 트리에서 maxNode로 함수를 호출하십시오.

def k_largest (self, node, k) : k <0 인 경우 :
k == 0 인 경우 None을 반환합니다. else : k-= 1 self를 반환합니다 .k_largest (self.predecessor (node), k)


0

자식 노드의 수를 저장하기 위해 원래 트리 노드를 수정할 필요가 없기 때문에 이것이 허용되는 대답보다 낫다고 생각합니다.

순서대로 순회를 사용하여 왼쪽에서 오른쪽으로 가장 작은 노드를 계산하고, 개수가 K와 같으면 검색을 중지하면됩니다.

private static int count = 0;
public static void printKthSmallestNode(Node node, int k){
    if(node == null){
        return;
    }

    if( node.getLeftNode() != null ){
        printKthSmallestNode(node.getLeftNode(), k);
    }

    count ++ ;
    if(count <= k )
        System.out.println(node.getValue() + ", count=" + count + ", k=" + k);

    if(count < k  && node.getRightNode() != null)
        printKthSmallestNode(node.getRightNode(), k);
}

0

이미 최선의 접근 방식이 있지만 이에 대한 간단한 코드를 추가하고 싶습니다.

int kthsmallest(treenode *q,int k){
int n = size(q->left) + 1;
if(n==k){
    return q->val;
}
if(n > k){
    return kthsmallest(q->left,k);
}
if(n < k){
    return kthsmallest(q->right,k - n);
}

}

int size(treenode *q){
if(q==NULL){
    return 0;
}
else{
    return ( size(q->left) + size(q->right) + 1 );
}}

0

보조 Result 클래스를 사용하여 노드가 발견되고 현재 k가 있는지 추적합니다.

public class KthSmallestElementWithAux {

public int kthsmallest(TreeNode a, int k) {
    TreeNode ans = kthsmallestRec(a, k).node;
    if (ans != null) {
        return ans.val;
    } else {
        return -1;
    }
}

private Result kthsmallestRec(TreeNode a, int k) {
    //Leaf node, do nothing and return
    if (a == null) {
        return new Result(k, null);
    }

    //Search left first
    Result leftSearch = kthsmallestRec(a.left, k);

    //We are done, no need to check right.
    if (leftSearch.node != null) {
        return leftSearch;
    }

    //Consider number of nodes found to the left
    k = leftSearch.k;

    //Check if current root is the solution before going right
    k--;
    if (k == 0) {
        return new Result(k - 1, a);
    }

    //Check right
    Result rightBalanced = kthsmallestRec(a.right, k);

    //Consider all nodes found to the right
    k = rightBalanced.k;

    if (rightBalanced.node != null) {
        return rightBalanced;
    }

    //No node found, recursion will continue at the higher level
    return new Result(k, null);

}

private class Result {
    private final int k;
    private final TreeNode node;

    Result(int max, TreeNode node) {
        this.k = max;
        this.node = node;
    }
}
}

0

Python 솔루션 시간 복잡성 : O (n) 공간 복잡성 : O (1)

아이디어는 Morris Inorder Traversal 을 사용하는 것입니다.

class Solution(object):
def inorderTraversal(self, current , k ):
    while(current is not None):    #This Means we have reached Right Most Node i.e end of LDR traversal

        if(current.left is not None):  #If Left Exists traverse Left First
            pre = current.left   #Goal is to find the node which will be just before the current node i.e predecessor of current node, let's say current is D in LDR goal is to find L here
            while(pre.right is not None and pre.right != current ): #Find predecesor here
                pre = pre.right
            if(pre.right is None):  #In this case predecessor is found , now link this predecessor to current so that there is a path and current is not lost
                pre.right = current
                current = current.left
            else:                   #This means we have traverse all nodes left to current so in LDR traversal of L is done
                k -= 1
                if(k == 0):
                    return current.val
                pre.right = None       #Remove the link tree restored to original here 
                current = current.right
        else:               #In LDR  LD traversal is done move to R 
            k -= 1
            if(k == 0):
                return current.val
            current = current.right

    return 0

def kthSmallest(self, root, k):
    return self.inorderTraversal( root , k  )

-1

k 번째로 작은 요소를 계산하는 깔끔한 함수를 작성했습니다. 순회 순회를 사용하고 k 번째 가장 작은 요소에 도달하면 중지합니다.

void btree::kthSmallest(node* temp, int& k){
if( temp!= NULL)   {
 kthSmallest(temp->left,k);       
 if(k >0)
 {
     if(k==1)
    {
      cout<<temp->value<<endl;
      return;
    }

    k--;
 }

 kthSmallest(temp->right,k);  }}

이것이 최적 인 이유에 대한 메트릭이 제공되지 않았습니다. 크고 작은 경우 모두
Woot4Moo

-1
int RecPrintKSmallest(Node_ptr head,int k){
  if(head!=NULL){
    k=RecPrintKSmallest(head->left,k);
    if(k>0){
      printf("%c ",head->Node_key.key);
      k--;
    }
    k=RecPrintKSmallest(head->right,k);
  }
  return k;
}

2
코드가 수행하는 작업과 문제 해결에 도움이되는 방법에 대한 설명과 함께 항상 코드를 첨부하십시오.
Ren

-1
public TreeNode findKthElement(TreeNode root, int k){
    if((k==numberElement(root.left)+1)){
        return root;
    }
    else if(k>numberElement(root.left)+1){
        findKthElement(root.right,k-numberElement(root.left)-1);
    }
    else{
        findKthElement(root.left, k);
    }
}

public int numberElement(TreeNode node){
    if(node==null){
        return 0;
    }
    else{
        return numberElement(node.left) + numberElement(node.right) + 1;
    }
}

-1
public static Node kth(Node n, int k){
    Stack<Node> s=new Stack<Node>();
    int countPopped=0;
    while(!s.isEmpty()||n!=null){
      if(n!=null){
        s.push(n);
        n=n.left;
      }else{
        node=s.pop();
        countPopped++;
        if(countPopped==k){
            return node;
        }
        node=node.right;

      }
  }

}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.