이진 트리가 검색 트리인지 테스트하고 전체 분기를 계산하는 알고리즘


10

이진 트리가 이진 검색 트리인지 확인하고 전역 계산 변수를 가정하여 얼마나 많은 완전한 분기가 있는지 (왼쪽 및 오른쪽 자식 노드가있는 부모 노드)를 계산하는 재귀 알고리즘을 만들어야합니다. 이것은 내 데이터 구조 클래스에 대한 할당입니다.

지금까지

void BST(tree T) {
   if (T == null) return
   if ( T.left and T.right) {
      if (T.left.data < T.data or T.right.data > T.data) {
        count = count + 1
        BST(T.left)
        BST(T.right)
      }
   }
}

그러나 나는 이것을 정말로 알아낼 수 없다. 두 번째 if 문이 true가 아닌 경우 카운트가 0이기 때문에이 알고리즘으로 문제를 해결할 수 없다는 것을 알고 있습니다.

아무도 나를 도울 수 있습니까?


비교 연산자 <는 노드에서 어떻게 정의됩니까?
Joe

이진 검색 트리가 아니더라도 카운트를 계산 하시겠습니까?
Joe

1
알고리즘이 true또는 과 같은 것을 반환해야 false합니까?
Joe

2
어쩌면 먼저 두 가지 별도의 함수를 정의해야 할 것입니다. 하나는 BST인지 확인하고 다른 하나는 전체 분기를 계산하기위한 것입니다. 더 관리하기 쉬워야합니다.
sepp2k

1
@OghmaOsiris 나는 그가 질문이 기본적으로 "여기에 내 코드가 있는데 어떻게 작동하게합니까?"라고 말했다. 코드가 유사 (ish) 종류가 아닌 경우에는 분명히 SO 질문 일 것입니다.
sepp2k

답변:


10

다른 사람들이 이미 주석에 표시했듯이 트리에는 검색 트리인지 테스트하고 전체 분기를 계산하는 두 가지 관련이 없습니다. 과제가 특별히 요구하지 않는 한 두 가지 별도의 함수를 작성합니다.

전체 분기를 먼저 계산하는 것을 보자. 즉, 왼쪽 자식과 오른쪽 자식이 모두있는 노드를 계산하는 것을 의미합니다. 그런 다음 카운터를 (증가해야 할 count = count + 1) 때 모두 T.leftT.rightnull가 아닌 (하지 T.left.dataT.right.data: 데이터는이 작업을 위해 중요하지 않습니다).

if (T.left and T.right) {
    count = count + 1

또한 오른쪽 하위 트리가 비어 있어도 왼쪽 하위 트리를 탐색해야하며 왼쪽 하위 트리가 비어 있어도 오른쪽 하위 트리를 탐색해야합니다. 재귀 호출을하는 위치를 확인하십시오.

트리가 검색 트리인지 테스트하려면 데이터 값을 검사해야합니다. 이미 올바른 비교에 가깝습니다. 별로 요 다양한 모양 (큰 노드는 아니지만 2-5 노드)을 가진 몇 가지 예제 트리를 작성하고 알고리즘을 실행하여 결과를 확인하십시오.

유효성 검사 결과를 넣을 곳을 여전히 찾아야합니다. 다시, 당신이 재귀 호출을 어디에 넣었는지 살펴보십시오 (이 부분 만 수행하면 몇 가지 해결책이 있지만이 단계에서는 하나만 보더라도 걱정하지 마십시오).

마지막으로 두 함수를 개별적으로 작성하고 몇 가지 예에서 테스트 한 후 신중하게 정리하십시오 (지정에 필요한 경우).


고마워, 나는 질문을 다시 읽고 그것은 별도의 방법이어야한다고 생각했다.
OghmaOsiris

7

이와 같은 상황에서는 종종 뒤로 생각하는 것이 더 쉬우므로 먼저 필요한 것을 고려하십시오. 설명에서 다음을 나열하십시오.

  • 재귀
  • 타당성
  • 완전한 노드 수

자, 그것은 상당히 짧은 목록입니다. 이것은 관리 가능해야합니다. 빈 메소드로 시작해 봅시다. 무슨 일이 일어나야하는지 설명하겠습니다.

valid_bst () {
}

이제 타당성. 유효성을 어떻게 확인합니까? 채팅에서 당신은 나무가 유효하다고 말했다. 평등을 허용해야한다고 확신합니다. 그렇습니다 t.left.value <= t.value <= t.right.value.

valid_bst () {
    This node is valid if t.left.value <= t.value <= t.right.value
}

그러나 어린이 중 하나가 없으면 어떻게해야합니까? 당신이 말한 것에서, 하나 또는 둘 다 누락 된 경우 노드가 여전히 유효하다는 것을 알고 있습니다. 이것을 약간 추가하여 약간의 구조 조정을 해보자 :

valid_bst () {
    This node is valid to the left if 
        there is no left child or 
        it is no greater than the current node.
    This node is valid to the right if 
        there is no right child or 
        it is no less than the current node.
    This node is valid overall if it is valid to the left and right.
}

이제이 노드가 유효한지 알았습니다. 전체 트리가 유효한지 어떻게 확인합니까? 배열에 없으므로 선형으로 반복 할 수는 없습니다. 당신의 임무는 답을 제공합니다 : 재귀. 그러나 재귀를 사용하여 어떻게 답을 축적합니까? 이 노드가 유효한지 여부와 왼쪽 및 오른쪽 노드가 유효한지 묻는 호출 결과에 대한 세 가지 정보에 액세스 할 수 있습니다. 분명히 나무는 세 가지가 모두 참인 경우에만 유효합니다.

valid_bst () {
    This node is valid to the left if 
        there is no left child or 
        it is no greater than the current node.
    This node is valid to the right if 
        there is no right child or 
        it is no less than the current node.
    This node is valid overall if it is valid to the left and right.
    Is the left child valid?
    Is the right child valid?
    This tree is only valid if this node and both its children are.
}

당신이주의를 기울이고 있다면, 그것은 우리의 기능이 무엇을 반환 해야하는지 알려줍니다.

이제 계산을 어떻게 통합합니까? 무엇을 계산할 것인지 ( "왼쪽 및 오른쪽 자식 노드가 모두있는 부모 노드") 실제 코드로 해석하기 어렵지 않아야합니다. 해당 조건이 만족되는지 확인하고 카운터를 적절하게 늘리십시오. 이것이 사실 일 때마다 도달 할 수있는 곳에 있어야한다는 것을 기억하십시오.

물론 재귀 중지 조건과 같은 세부 정보를 생략하고 null을 확인합니다.


6

위의 세 가지 의견은 코드 문제에 대한 세 가지 힌트입니다.

  1. 비교 연산자가 노드 데이터 유형을 처리하는 방법을 이미 구체적으로 정의하지 않은 경우 두 노드를 직접 비교하면 원하는 작업이 수행되지 않습니다. 아마도 의미는 노드에 저장된 필드를 비교하는 것입니다.node1.value < node2.value
  2. 지금, 당신은 세 번째 if가 사실 인 경우에만 카운트에 추가하는 것입니다, 당신은 당신이 의도 한 것이 확실합니까? 그건 그렇고, if 문이 원하는 것을 수행하는지 다시 확인하고 싶을 수도 있습니다.
  3. 트리가 유효한 BST이면 true를 반환하고 그렇지 않으면 false를 반환한다고 가정합니다. 즉, 기본 사례에서는 항상 true 또는 false를 반환해야하며 재귀 호출의 결과도 반환해야합니다.

포인트 1에 관해서 : 이것은 의사 코드입니다. 따라서 의도가 독자에게 전달되는 한 그러한 것을 정의 할 이유가 없습니다.
sepp2k

@ sepp2k 그건 사실이며, 내 의견은 아마도 의사 코드에는 너무 까다 롭습니다. 내 요점은 두 노드를 비교하는 것이 무엇을 의미하는지 이해해야한다는 것입니다. 당신의 요점은 우리가 이미 암묵적으로 이해해야한다는 것입니다.
Joe

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