이진 트리 회전


16

균형 이진 검색 트리는 O (log n) 조회 (또는 유사한 작업) 를 보장하는 데 필수적 입니다. 많은 키가 무작위로 삽입 및 / 또는 삭제되는 동적 환경에서 트리는 조회하기에 끔찍한 연결된 목록으로 생성 될 수 있습니다. 따라서이 효과를 막는 다양한 종류의 자체 균형 이진 트리 가 있습니다 (예 : AVL 트리 또는 splay 트리 ). 이 나무는 나무의 균형을 재조정 하는 여러 종류의 회전 을 기반으로 합니다.

회전

이 과제에서는 단일 오른쪽 회전 만 살펴볼 것입니다. 이러한 회전 (왼쪽 회전은 대칭이 됨)은 다음과 같습니다.

    5            3
   / \          / \
  3   6   =>   1   5
 / \              / \
1   4            4   6

나뭇잎 14있거나 6왼쪽 또는 오른쪽 하위 트리가있는 경우 회전은 단순히 해당 트리를 유지합니다. 이것이 더 큰 나무의 하위 트리 인 경우 노드에서 간단히 "잘라 내고" 5회전 된 트리 (현재 노드 3)를 해당 노드에 "재 부착" 합니다.

도전

이진 검색 트리 1 과 키가 위에서 설명한 것처럼 해당 노드에서 트리를 오른쪽으로 회전시킵니다. 위 예에서 제공된 키는입니다 5.

규칙 및 I / O

  • 선택한 키와 테스트 케이스의 키가 서로 다른 한 키에 대해 모든 유형을 사용할 수 있습니다.
  • 모호성이없고 (예를 들어 [3,[]]달리 명시되지 않는 한 모호한 경우) 이진 트리에 대한 표현을 선택할 수 있으며 선택한 언어에 적합합니다.
  • 입력은 항상 이진 검색 트리이므로 중복 키가 없습니다.
  • 키가 트리에 포함되어 있다고 가정 할 수 있습니다
  • 키를 포함하는 노드에 왼쪽 자식이 있다고 가정 할 수 있습니다
  • 제공된 키 아래에 올바른 하위 트리를 가정 할 수 없습니다
  • 당신은 회전하기 전에 나무가 불균형하다고 가정 하지 않을 수 있습니다
  • 당신은 회전 후 나무가 균형이 있다고 가정 하지 않을 수 있습니다
  • 기본 I / O 방법을 사용할 수 있습니다
  • 제출물은 트리를 반환하는 함수이거나 솔루션을 인쇄하는 전체 프로그램 일 수 있습니다.

테스트 사례

이 예제는 다음과 같이 트리를 나타냅니다.

  • 그것이 잎이라면 : []
  • 키가있는 트리 x이고 두 하위 트리가 모두 잎 인 경우 :[x]
  • x와 하위 트리가있는 트리 인 경우 left right:[x,left,right]

첫 번째 예는 회전 섹션에 제공된 예입니다 . 어떤 이유로 당신이 그들의 그래픽 표현을해야하는 경우, 여기에 2 당신은 간다.

5 [5,[3,[1],[4]],[6]]  ->  [3,[1],[5,[4],[6]]]
5 [5,[3,[1],[4]],[]]  ->  [3,[1],[5,[4],[]]]
5 [5,[3,[],[4]],[6]]  ->  [3,[],[5,[4],[6]]]
5 [5,[3,[1],[]],[]]  ->  [3,[1],[5]]
4 [8,[4,[2,[1],[3]],[6,[5],[7]]],[12,[10,[9],[11]],[14,[13],[15]]]]  ->  [8,[2,[1],[4,[3],[6,[5],[7]]]],[12,[10,[9],[11]],[14,[13],[15]]]]
8 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]]  ->  [10,[6,[4,[2,[],[3]],[5]],[8,[7],[9]]],[11]]
10 [10,[8,[6,[4,[2,[],[3]],[5]],[7]],[9]],[11]]  ->  [8,[6,[4,[2,[],[3]],[5]],[7]],[10,[9],[11]]]
9 [6,[3,[2],[5]],[9,[8],[12,[11],[15,[14],[]]]]]  ->  [6,[3,[2],[5]],[8,[],[9,[],[12,[11],[15,[14],[]]]]]]
7 [7,[5,[3,[1],[4]],[6]],[8]]  ->  [5,[3,[1],[4]],[7,[6],[8]]]
15 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]  ->  [17,[9,[5,[2,[0],[4]],[8]],[13,[11,[10],[12]],[15,[14],[16]]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]
21 [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[21,[19,[18],[20]],[24,[22],[25]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]  ->  [17,[9,[5,[2,[0],[4]],[8]],[15,[13,[11,[10],[12]],[14]],[16]]],[40,[27,[19,[18],[21,[20],[24,[22],[25]]]],[28]],[44,[42,[41],[]],[51,[47],[59,[55],[61]]]]]]

1 : 모든 노드에서 왼쪽 하위 트리의 모든 키가 해당 키보다 작고 오른쪽 하위 트리의 모든 키가 그보다 큰 것을 의미

2 : 링크 로트를 방지하기 위해 주석으로 포함 시켰습니다.

답변:


8

하스켈 , 93 92 84 83 82 바이트

data B=B[B]Int|L
k!B[l@(B[x,y]a),r]n|k<n=B[k!l,r]n|k>n=B[l,k!r]n|1>0=B[x,B[y,r]k]a

@BMO 덕분에 @alephalpha와 @Laikoni는 각각 1 바이트, @nimi는 8 바이트입니다!

온라인으로 사용해보십시오!


를 사용하면 data B=B[B]Int더 많은 바이트가 절약됩니다.
Laikoni

@ Laikoni 단지 1 바이트 내가 생각하지만 걸릴 것이다
Angs

먼저 두 사건을 병합에 의해 2 바이트를 절약 할 수 k<n=B[k!l,r]nk>n=B[l,k!r]n: 하나에 k/=n=B[k!l,k!r]n다음 추가 k!x=x패턴 매칭 철저한를 만들기 위해.
Radek

5

Vim , 25 바이트

공백으로 구분 된 키와 트리-버퍼에 입력을받습니다. 나무는 다음과 같이 표현 될 것으로 예상됩니다 :

  • 잎: []
  • 키가있는 노드 k, 왼쪽 자식 <left>및 오른쪽 자식 <right>:[ k <left><right>]

키 주위의 공간 k이 중요 하지 않으므로 솔루션이 임의의 트리에서 작동합니다.

"adw/ <C-r>a⏎3dw%l"apr[%xl%i]

온라인으로 사용해보십시오!

설명

"adw                           " delete the key and trailing space, keep in register a
    / <C-r>a⏎                  " move cursor to the key surrounded with spaces
             3dw               " remove key and [ (move left node to top)
                %l             " move cursor to the right subtree
                  "ap          " insert key there
                     r[        " insert a [ (appending subtree to key)
                       %       " move to the end of new left subtree
                        x      " remove ] (fix parentheses)
                         l%    " move to the end of new right subtree
                           i]  " insert ] (fix parentheses)

시사

다음 은 Lynn 이이 스크립트로 생성 한 첫 번째 테스트 사례의 미리보기입니다 .

                       Vim 미리보기


3

Wolfram Language (Mathematica) , 30 바이트

#2/.a_~b_~c_~#~d_:>b[a,c~#~d]&

온라인으로 사용해보십시오!

나무는 다음과 같이 표현됩니다.

  • 그것이 잎이라면 : $(키가 아닌 다른 값으로 대체 할 수 있습니다)
  • x와 하위 트리가있는 트리 인 경우 left right:x[left,right]

예를 들어 첫 번째 테스트 사례의 트리는로 표시됩니다 5[3[1[$,$],4[$,$]],6[$,$]].

설명:

#2                                the second input
  /.                              replace
    a_~b_~c_~#~d_                 #[b[a,c],d], where # is the first input
                 :>               by
                   b[a,c~#~d]     b[a,#[c,d]]
                             &    define a function

3

공통 리스프, 146 바이트

(defun r(k a)(cond((not a)a)((=(car a)k)`(,(caadr a),(cadadr a)(,(car a),(car(cddadr a)),(caddr a))))(t`(,(car a),(r k(cadr a)),(r k(caddr a))))))

온라인으로 시도 하거나 모든 테스트 케이스를 확인하십시오!

나무는 다음과 같이 표현됩니다.

  • 빈 트리는 다음과 같이 표시됩니다 nil(또는 Common Lisp에서 빈 목록과 동일 함).() )
  • 비어 있지 않은 트리는 세 요소의 목록으로 표시됩니다 (node left-subtree right-subtree) (그래서 리프 L는로 (L nil nil)표시됨).

2

자바 스크립트 (Node.js) , 70 바이트

n=>f=a=>n-a[0]?(a[i=n<a[0]?1:2]=f(a[i]),a):(i=a[1],a[1]=i[2],i[2]=a,i)

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 모든 노드에는 왼쪽 및 오른쪽 항목이 있어야하지만 []해당 측면에 하위 트리가 없음을 나타낼 수 있습니다 . 약어로서 테스트 스위트는 리프 임을 표시하고 입력 및 출력 모두에 왼쪽 서브 트리가 있지만 오른쪽 서브 트리가 없음 l(N)을 나타내는 데 사용 합니다 .Nl(N,L)NL



1

젤리 , 24 바이트

ñ
Ḣ,1ịṪƊṭ@ṪṭḢð{Ḣ;ç€ɗ¹¡i?

온라인으로 사용해보십시오!

경고 : 일반적으로 맨 위 줄은 존재하지 않아야하며 맨 아랫 줄 ß에는ç . 그러나 영리한 체인 트릭과ß 함께 잘 않습니다.ß의 가변 arity. 기술적으로, 나는 여전히 맨 위 줄을 생략 할 수 있었지만 결과는 전체 프로그램이어야했습니다. 그렇지 않으면 모든 프로그램 내에서 자체 줄로 통합 할 수 있어야하기 때문에 가능하지 않습니다. 운이 좋다 불행히도, 전체 프로그램을 제출할 때 실제로 출력 카운트를 얻는 것이지 프로그램이 닫히기 전에 기술적으로 결과가 나오지 않기 때문에 출력에 애매한 표현이 있었음을 의미합니다. 따라서 재귀와 적절한 문자열 표현으로 혼란을 피하기 위해 최상위 줄의 작업이 맨 아래 줄을 호출하는 2 줄 함수를 제출하기로 결정했습니다. 결과? 귀중하고 귀중한 2 바이트의 엄청난 낭비. 젤리 (및 데니스 및 다른 모든 기고자) 방어에서

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