2014-01-26 5 views
0

나는 어제 비슷한 질문을했지만, 원래 질문에 게시 된 것과 다른 해결책을 찾았습니다. 새 코드로 다시 게시하고 있습니다. 각 노드의 오른쪽 및 왼쪽 자식 수를 추적하지 않습니다. 이 코드는 경우에 따라 정상적으로 작동하지만 6 번째로 작은 요소를 찾은 경우 실패합니다. 문제는 내가 어떻게 든 나무 아래로 많은 수의 아이들을 태울 필요가 있다는 것이다. 예를 들어, 노드 5의 경우, 노드 4의 계급 이상으로 캐리해야하며이를 수행 할 수 없습니다.BST에서 k 번째로 작은 노드를 찾는 방법은 무엇입니까?

이것은 숙제가 아니기 때문에 인터뷰 준비 중입니다. 이것은 고전적인 질문 중 하나이며 해결할 수 없습니다.

class Node: 
    """docstring for Node""" 
    def __init__(self, data): 
     self.data = data 
     self.left = None 
     self.right = None 
     self.numLeftChildren = 0 
     self.numRightChildren = 0 


class BSTree: 
    def __init__(self): 
     # initializes the root member 
     self.root = None 

    def addNode(self, data): 
     # creates a new node and returns it 
     return Node(data) 

    def insert(self, root, data): 
     # inserts a new data 
     if root == None: 
      # it there isn't any data 
      # adds it and returns 
      return self.addNode(data) 
     else: 
      # enters into the tree 
      if data <= root.data: 
       root.numLeftChildren += 1 
       # if the data is less than the stored one 
       # goes into the left-sub-tree 
       root.left = self.insert(root.left, data) 
      else: 
       # processes the right-sub-tree 
       root.numRightChildren += 1 
       root.right = self.insert(root.right, data) 
      return root 

    def getRankOfNumber(self, root, x, rank): 
     if root == None: 
      return 0 
     if rank == x: 
      return root.data 
     else: 
      if x > rank: 
       return self.getRankOfNumber(root.right, x, rank+1+root.right.numLeftChildren) 
      if x <= rank: 
       return self.getRankOfNumber(root.left, x, root.left.numLeftChildren+1) 


# main 
btree = BSTree() 
root = btree.addNode(13) 
btree.insert(root, 3) 
btree.insert(root, 14) 
btree.insert(root, 1) 
btree.insert(root, 4) 
btree.insert(root, 18) 
btree.insert(root, 2) 
btree.insert(root, 12) 
btree.insert(root, 10) 
btree.insert(root, 5) 
btree.insert(root, 11) 
btree.insert(root, 8) 
btree.insert(root, 7) 
btree.insert(root, 9) 
btree.insert(root, 6) 

print btree.getRankOfNumber(root, 8, rank=root.numLeftChildren+1) 
+1

왜 inorder iterator를 정의하고 그것이 산출 한'k' 번째의 것을 반환하지 않는가? – user2357112

+0

http://stackoverflow.com/questions/21359873/in-order-bst-traversal-find/21359973하지만 올바른 답을 얻을 수 없었습니다. – Anastasia

+0

추가 데이터 구조를 사용하지 않으려합니다. 나는 inorder traversal을 할 수 있고, 모든 것을 배열에 저장하고 k 번째 값을 반환 할 수 있다는 것을 이해합니다. 그러나 이것은 내가 찾고있는 것이 아닙니다. 재귀 등을 사용할 때 오류가 발생하는 곳을보고자 노력 중입니다. – Anastasia

답변

0

노드 등급이 있습니다. 왼쪽 또는 오른쪽 자식의 순위를 찾아야합니다. 노드와 그 자식 사이에 몇 개의 노드가 있습니까?

 a 
    /\ 
/ \ 
    b  c 
/\ /\ 
W X Y Z 

다음은 BST의 예입니다. 소문자는 노드입니다. 대문자는 하위 트리입니다. ab 사이의 노드 수는 X의 노드 수입니다. ac 사이의 노드 수는 Y의 노드 수입니다. 따라서 b 또는 c의 순위를 a의 순위와 X 또는 Y의 크기에서 계산할 수 있습니다.

rank(b) == rank(a) - size(X) - 1 
rank(c) == rank(a) + size(Y) + 1 

당신은 c 공식하지만 잘못된 b 공식을했다.

+0

여기 내 문제입니다. 이 특정 트리에서 http://lcm.csa.iisc.ernet.in/dsa/node91.html 5보다 작은 노드 수는 4보다 작은 노드 수 + 5의 왼쪽 하위 노드 수와 같습니다. 10 및 12 건너 뛰기 – Anastasia

+0

@Anastasia : "Skip"10 및 12? 그것이 당신이하고 싶은 일이라면 당신은 과거를 뛰어 넘을 수 없을 것입니다. 그러나 제가 제공 한 공식은 계급 계산을 올바르게 처리해야합니다. – user2357112

+0

그래서 x <= rank에 대한 표현식을 self.getRankOfNumber (root.left, x, rank-1-root.left.numLeftChildren)를 반환하도록 수정해야한다고 말하고 있습니다. 이것은 올바른 해결책을 제공하지 않습니다. 예를 들어, 1을 8 번째로 작은 요소로 반환합니다. – Anastasia

관련 문제