두 개의 AVL 나무를 연결/병합/합류합니다
-
19-09-2019 - |
문제
내가 두 개의 AVL 나무가 있고 첫 번째 나무의 각 요소가 두 번째 나무의 요소보다 작다고 가정합니다. 하나의 단일 AVL 트리에 연결하는 가장 효율적인 방법은 무엇입니까? 나는 어디에서나 검색했지만 유용한 것을 찾지 못했습니다.
해결책
입력 트리를 파괴 할 수 있다고 가정합니다.
- 왼쪽 트리의 가장 오른쪽 요소를 제거하고이를 사용하여 왼쪽 자식이 왼쪽 나무이며 오른쪽 아이가 오른쪽 나무 인 새 루트 노드를 구성하는 데 사용하십시오. O (log n).
- 해당 노드의 밸런스 계수를 결정하고 설정하십시오 : O (log n). 불변의 (임시) 위반에서 균형 계수는 범위 {-1, 0, 1} 범위를 벗어날 수 있습니다.
- 밸런스 계수를 범위로 되돌려 놓기 위해 회전합니다 : O (log n) 회전 : O (log n)
따라서 전체 작업은 O (log n)에서 수행 될 수 있습니다.
편집 : 두 번째 생각에서 다음 알고리즘의 회전에 대해 추론하기가 더 쉽습니다. 또한 더 빠를 가능성이 높습니다.
- 양쪽 나무의 높이를 결정하십시오 : O (log n).
오른쪽 나무가 키가 크다고 가정하면 (다른 경우는 대칭 적) : - 가장 오른쪽 요소를 제거하십시오
left
트리 (필요한 경우 계산 된 높이 회전 및 조정). 허락하다n
그 요소가 되십시오. O (로그 N) - 오른쪽 트리에서 하위 트리가 최대 1 개의 키가 큰 노드에 도달 할 때까지 왼쪽을 탐색
left
. 허락하다r
그 노드가 되십시오. O (로그 N) 해당 노드를 새 노드로 값 n 및 하위 트리로 바꾸십시오.
left
그리고r
. o (1)
시공으로 새로운 노드는 AVL 균형을 잡고 하위 트리 1이r
.그에 따라 부모의 균형을 늘리십시오. o (1)
- 그리고 삽입 한 후 당신처럼 재조정합니다. O (로그 N)
다른 팁
하나의 매우 간단한 솔루션 (나무 사이의 관계에 대한 가정없이 작동)은 다음과 같습니다.
- 두 나무를 하나의 합병 어레이로 합병하십시오 (동시에 두 나무를 반복).
- 배열에서 AVL 트리를 만들 - 중간 요소를 뿌리로 삼고 왼쪽과 오른쪽 반쪽에 재귀 적으로 바르십시오.
두 단계 모두 O (n)입니다. 주요 문제는 O (N) 추가 공간이 필요하다는 것입니다.
나는 당신이 단지 하나의 나무를 걸어 가야한다고 생각합니다 (희망적으로 더 작은). 다른 나무에 각각의 요소를 개별적으로 추가해야합니다. AVL 삽입/삭제 작업은 한 번에 전체 하위 트리를 추가하도록 설계되지 않았습니다.
제휴하지 않습니다 StackOverflow