데이터 구조 - 이진 검색 트리 (이진 검색 트리)

이진 검색 트리

이진 검색 트리 이진 트리도 이진 검색 트리로 알려진 가장 일반적인 유형입니다.

이름에서 알 수 있듯이, 순서 이진 검색 트리를 신속하게 달성 찾아 학생들합니다.

사실, 빨리 그것의 지원에 추가하여 데이터를 신속하게 삽입에 대한 추가 지원, 삭제 된 데이터를 찾을 수 있습니다.

특정 이진 검색 트리 구조에 따라 다음을 지원할 수있다.

 

이진 검색 트리의 트리의 노드를 필요 좌측 서브 트리의 값의 각각의 노드는 노드의 값 이하로,이 노드의 우측 서브 트리의 노드 값이 값보다 더 크다.

 

조작 트리 이진 트리 모양

첫 번째 테이크 뿌리, 그 다음 반환 우리가 찾고있는 데이터와 동일한 경우.

이 데이터는 루트 노드의 값보다 작은 찾으려면, 다음 재귀 왼쪽 서브 트리에 보이는;

루트 노드의 값보다 데이터 큰 찾고 있다면, 다음 재귀 적 권리 서브 트리를 찾을 수 있습니다.

 

이진 탐색 트리 삽입

이진 탐색 트리 삽입 프로세스는 검색 작업에 다소 유사하다.

새로운 데이터는 일반적으로 차례로 데이터 사이의 크기 관계가 삽입 노드 수 비교, 리프 노드에서 우리는 루트에서 시작해야 삽입됩니다.

데이터가 큰 데이터 노드에 걸쳐 삽입, 오른쪽 하위 트리의 노드가 비어있는 경우, 새로운 데이터가 직접 우측 자식 노드의 위치를 ​​삽입됩니다;

비어 있지 않은 경우, 반복적으로 오른쪽 서브 트리를 통과 삽입 위치를 찾을 수 있습니다.

삽입되는 데이터가 노드의 값보다 작은 경우, 상기 노드의 좌측 서브 트리가 비어 있으면 마찬가지로, 새로운 데이터는 좌측 자식 노드의 위치에 삽입 될 것이다;

비어 있지 않은 경우, 반복적으로, 왼쪽 서브 트리를 통과 삽입 위치를 찾을 수 있습니다.

 

이진 검색 트리 삭제

더 복잡한 작업으로 삭제 작업을 찾아서 세 건으로 처리 할 필요가 삽입합니다.

 

당신이 노드에 자식 노드가 없습니다 삭제하려면 먼저 우리는, 단지 직접 부모 노드를 필요는 노드 포인터가 null로 설정되어 삭제할 가리입니다. (예를 들면, 그래프 (55) 내의 노드를 삭제하는 등)

노드는 하나의 자식 노드 (단지 왼쪽 자녀 또는 우측 자식 노드)를 제거하려는 경우 두 번째 경우는, 우리는 부모 노드를 업데이트해야합니다, 당신은 노드를 제거 할 자식 노드를 가리 키도록 노드 포인터를 삭제할 포인트 거기에. (예를 도시하는 노드를 삭제하는 등. 13)

세 번째 경우는 노드를 삭제하려면 더 복잡 두 아이를 가지고 있다는 것입니다. 우리는 삭제 될 노드에서 교체하려면 트리에서 가장 작은 노드의 오른쪽 자식 노드를 찾아야합니다. 최소 왼쪽 자식 노드 (왼쪽 자식 노드가있는 경우, 그것은 가장 작은 노드가 아닌) 확실하지 않기 때문에 가장 작은 노드를 제거하기 위해 위의 우리는이 규칙을 적용 할 수 있도록 그리고, 최소 노드를 삭제합니다. (도 1에 노드를 삭제하는 등. 18)

 

기타 영업 이진 검색 트리

이진 검색 트리의 삽입과 삭제 작업을 찾는 또, 신속하게 최대 및 최소 노드 노드 노드 전임자와 후임자 노드를 찾을 수에 대한 지원과 같은 많은 작업이있다.

이진 트리의 하나 개의 중요한 특성 이진 검색 트리 탐색 시퀀스 데이터 월 출력 정렬 순서 는 시간 복잡도는 O (N)을, 매우 효율적이다.

이 때문에, 또한 이진 검색 트리 이진 정렬 나무라고도합니다.

 

public class BinarySearchTree {
  private Node tree;

  public Node find(int data) {
    Node p = tree;
    while (p != null) {
      if (data < p.data) p = p.left;
      else if (data > p.data) p = p.right;
      else return p;
    }
    return null;
  }
  
  public void insert(int data) {
    if (tree == null) {
      tree = new Node(data);
      return;
    }

    Node p = tree;
    while (p != null) {
      if (data > p.data) {
        if (p.right == null) {
          p.right = new Node(data);
          return;
        }
        p = p.right;
      } else { // data < p.data
        if (p.left == null) {
          p.left = new Node(data);
          return;
        }
        p = p.left;
      }
    }
  }

  public void delete(int data) {
    Node p = tree; // p指向要删除的节点,初始化指向根节点
    Node pp = null; // pp记录的是p的父节点
    while (p != null && p.data != data) {
      pp = p;
      if (data > p.data) p = p.right;
      else p = p.left;
    }
    if (p == null) return; // 没有找到

    // 要删除的节点有两个子节点
    if (p.left != null && p.right != null) { // 查找右子树中最小节点
      Node minP = p.right;
      Node minPP = p; // minPP表示minP的父节点
      while (minP.left != null) {
        minPP = minP;
        minP = minP.left;
      }
      p.data = minP.data; // 将minP的数据替换到p中
      p = minP; // 下面就变成了删除minP了
      pp = minPP;
    }

    // 删除节点是叶子节点或者仅有一个子节点
    Node child; // p的子节点
    if (p.left != null) child = p.left;
    else if (p.right != null) child = p.right;
    else child = null;

    if (pp == null) tree = child; // 删除的是根节点
    else if (pp.left == p) pp.left = child;
    else pp.right = child;
  }

  public Node findMin() {
    if (tree == null) return null;
    Node p = tree;
    while (p.left != null) {
      p = p.left;
    }
    return p;
  }

  public Node findMax() {
    if (tree == null) return null;
    Node p = tree;
    while (p.right != null) {
      p = p.right;
    }
    return p;
  }
  
  public static class Node {
    private int data;
    private Node left;
    private Node right;

    public Node(int data) {
      this.data = data;
    }
  }
}

 

이진 검색 트리 시간 복잡도 분석

형태의 이진 검색 트리 다양한 동일한 데이터 집합에 대해, 동일하지 않습니다 이진의 다른 형태의 구현의 검색 트리, 삽입, 삭제 작업의 효율성을 찾을 수 있습니다.

시간 복잡성 모습 O (N)를가되도록도 처음 이진 검색 트리, 매우 고르지 왼쪽과 오른쪽 서브 트리의 루트는, 연결리스트로 전락했다. 

이것은 이진 검색 트리가 완전 이진 트리 (또는 완전 이진 트리) 시간이된다 이진 검색 트리 최악의 경우, 가장 좋은 경우입니다.

 

삽입 여부, 삭제 또는 높이가 실제로 O (높이) 인 트리, 관련이 시간 복잡성에 비례 찾을 수 있습니다.

어떻게 완전 이진 트리가 n 개의 노드의 높은 수준을 포함 ​​얻으려면?

n은 노드의 완전한 바이너리 트리가, 노드가 제 1 층을 포함 들어, 제 2 층은 제 3 층은 네 개의 노드를 포함하는 2 개 노드를 포함한다.

등등, 노드의 수는 아래의 층의 2 배 층, 제 K 층에 포함 된 노드의 수는 2 ^ (K-1)이다.

완전 이진 트리를 들어, 위의 법을 준수하지의 마지막 층의 노드 번호.

우리는 층의 최대 수를 L이라고 가정 노드의 수는 1 차 (L-1) ^ 2 사이의 하나를 포함한다.

n >= 1+2+4+8+...+2^(L-2)+1
n <= 1+2+4+8+...+2^(L-2)+2^(L-1)

[LOG2 (N + 1), log2n +1]의 범위에있는 형상 시퀀스 합산, L은 레이어 수 덜 완전한 바이너리 트리 log2n +1이고, 상기 트리의 높이는 층을 뺀 최대 수와 동일한

즉, 같거나 log2n 이하의 완전한 이진 트리의 높이입니다.

그러나,이 더 많은 상황을 균형 경우에만 이상적인 상황이다.

매우 불균형 이진 검색 트리의 성능은 확실히 수요를 충족하기 위해 보이지 않는다.

우리는 데이터를 삽입, 언제든지, 모든 노드 주위 유지할 수 있습니다, 하위 트리를 삭제를 구성해야하는지에 상관없이 더 이진 검색 트리를 균형 있습니다.

그럼 당신은 이진 검색 트리의 특별한 종류의 필요 - 균형 이진 검색 트리를

그래서 삽입, 삭제 작업의 시간 복잡도는 상대적으로 안정 발견, 이진 검색 트리 높이 닫기 logn을 균형이다 O (logn).

게시 된 113 개 원래 기사 · 원 찬양 25 ·은 30000 +를 볼

추천

출처blog.csdn.net/qq_42006733/article/details/104629382