안 드 로 이 드 데이터 구조 07 - AVL 트 리
1. AVL 트 리 의 기본 개념
1. AVL 트 리
AVL 트 리 는 각 노드 의 왼쪽 트 리 와 오른쪽 트 리 의 높이 차 이 는 최대 1 과 같은 자기 평형 이 진 트 리 입 니 다.
AVL 트 리 는 일반적인 이 진 트 리 보다 검색 효율 이 높 지만 삽입 삭제 효율 이 낮 습 니 다.
2. 평형 인자
밸 런 스 인자 (BF: Balance Factor) 는 이 진 트 리 에 있 는 노드 의 왼쪽 트 리 깊이 에서 오른쪽 트 리 깊이 를 뺀 값 입 니 다.
3. 최소 불 균형 서브 트 리
최소 불 균형 서브 트 리 는 삽입 노드 에서 가장 가 깝 고 균형 인자 의 절대 치가 1 보다 큰 노드 가 뿌리 인 서브 트 리 입 니 다.
노드 A 를 추가 한 후에 나무의 깊이 가 + 1 이면 A 의 모든 부모 노드 의 균형 인자 의 절대 치 는 + 1 이 되 고 A 와 가장 가 까 우 며 균형 인자 의 절대 치가 1 보다 큰 노드 B 는 전체 나무의 불 균형 을 초래 하 는 요소 이다. B 의 모든 부모 노드 의 균형 인자 가 B 를 삽입 하기 전에 0 이 될 것 이기 때문이다.
2. AVL 트 리 의 조작
AVL 트 리 의 삽입 은 항상 회전 이 필요 합 니 다. 왼쪽 회전 과 오른쪽 회전 입 니 다.
1. 좌선
왼쪽 회전 은 노드 A 를 A 의 오른쪽 노드 B 의 왼쪽 노드 로 바 꾸 고 B 의 원래 왼쪽 노드 를 A 의 오른쪽 노드 로 바 꾸 는 것 이다. 즉, A 를 왼쪽으로 한 명 아래로 옮 기 는 것 이다.
public void leftRoate(Node node) {
if (node == null) {
return;
}
Node right = node.right;
// 1. node node
node.right = right.left;
if (right.left != null) {
right.left.parent = node;
}
// 2. node node
right.parent = node.parent;
if (node.parent == null) {
root = right;
} else if (node.parent.right == node) {
node.parent.right = right;
} else if (node.parent.left == node) {
node.parent.left = right;
}
// 3. node node
right.left = node;
node.parent = right;
}
2. 우회전
오른쪽 회전 은 노드 A 를 A 의 왼쪽 노드 B 의 오른쪽 노드 로 바 꾸 고 B 의 원래 오른쪽 노드 를 A 의 왼쪽 노드 로 바 꾸 는 것 이다. 즉, A 를 오른쪽으로 한 명 이동 하 는 것 이다.
public void rightRoate(Node node) {
if (node == null) {
return;
}
Node left = node.left;
// 1. node node
node.left = left.right;
if (left.right != null) {
left.right.parent = node;
}
// 2. node node
left.parent = node.parent;
if (node.parent == null) {
root = left;
} else if (node.parent.left == node) {
node.parent.left = left;
} else if (node.parent.right == node) {
node.parent.right = left;
}
// 3. node node
left.right = node;
node.parent = left;
}
3. AVL 트 리 의 삽입
AVL 트 리 의 삽입 은 매우 복잡 해서 세 단계 로 나 눌 수 있 습 니 다. 추가, 균형 검사, 균형 수정.
여기에 새로 추 가 된 노드 를 A 로 기록 하고 A 의 부모 노드 를 B 로 기록 하 며 찾 은 최소 불 균형 서브 트 리 를 C 로 기록 합 니 다.
1. 추가
첫 번 째 단 계 는 두 갈래 검색 트 리 의 삽입 과 같 습 니 다.
2. 밸 런 스 체크
(1) A 가 왼쪽 노드 라면 B 의 균형 인자 + 1;A 가 오른쪽 노드 라면 B 의 균형 인자 - 1.
(2) B 의 균형 인 자 를 판단 한다.
3. 밸 런 스 수정
마지막 단계 에서 찾 은 최소 불 균형 서브 트 리 C 를 수정 하면 4 가지 상황 으로 나 눌 수 있 습 니 다.
4. 코드 구현
요소 추가:
public void put(E data) {
Node now = new Node(data);
if (root == null) {
root = now;
return;
}
Node parent = root;
// :
while (parent != null) {
if (data.compareTo(parent.data) < 0) {
if (parent.left == null) {
parent.left = now;
now.parent = parent;
break;
} else {
parent = parent.left;
}
} else if (data.compareTo(parent.data) > 0) {
if (parent.right == null) {
parent.right = now;
now.parent = parent;
break;
} else {
parent = parent.right;
}
} else {
return;
}
}
// ,
while (parent != null) {
// , +1
if (data.compareTo(parent.data) < 0) {
parent.bran++;
// , -1
} else {
parent.bran--;
}
if (parent.bran == 0) {
break;
} else if (Math.abs(parent.bran) == 2) {
//
fixAfterInsertion(parent);
break;
} else {
parent = parent.parent;
}
}
}
수정 위치:
private void fixAfterInsertion(Node parent) {
if (parent.bran == 2) {
leftBranch(parent);
}
if (parent.bran == -2) {
rightBranch(parent);
}
}
왼쪽 트 리 동작:
public void leftBranch(Node node) {
if (node == null) {
return;
}
Node left = node.left;
//
if (left.bran == LH) {
rightRoate(node);
// 0
node.bran = EH;
left.bran = EH;
// , 。
} else if (left.bran == RH) {
Node lr = left.right;
leftRoate(left);
rightRoate(node);
//2 ,left lr ,node lr
if (lr.bran == LH) {
node.bran = RH;
left.bran = EH;
lr.bran = EH;
} else if (lr.bran == RH) {
node.bran = EH;
left.bran = LH;
lr.bran = EH;
// lr
} else if (lr.bran == EH) {
node.bran = EH;
left.bran = EH;
lr.bran = EH;
}
}
}
오른쪽 하위 트 리 조작:
public void rightBranch(Node node) {
if (node == null) {
return;
}
Node right = node.right;
//
if (right.bran == RH) {
leftRoate(node);
// 0
node.bran = EH;
right.bran = EH;
// , 。
} else if (right.bran == LH) {
Node rl = right.left;
rightRoate(right);
leftRoate(node);
//2 ,right rl ,node rl
if (rl.bran == LH) {
node.bran = EH;
right.bran = RH;
rl.bran = EH;
} else if (rl.bran == RH) {
node.bran = LH;
right.bran = EH;
rl.bran = EH;
// rl
} else if (rl.bran == EH) {
node.bran = EH;
right.bran = EH;
rl.bran = EH;
}
}
}
4. AVL 트 리 의 삭제
AVL 트 리 에서 삭제 하면 삭제 할 노드 를 아래로 한 잎 노드 로 회전 시 킨 다음 에 이 잎 노드 를 직접 잘라 서 완성 할 수 있 습 니 다.
코드 없 음...
5. AVL 트 리 찾기
AVL 트 리 찾기 는 이 진 트 리 찾기 와 같 습 니 다.
마지막.
코드 주소:https://gitee.com/yanhuo2008/Common/blob/master/Tool/src/main/java/gsw/tool/datastructure/tree/TreeAVL.java
데이터 구조 와 알고리즘 테마:https://www.jianshu.com/nb/25128590
좋아요, 좋아요, 감사합니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.