최대 힙입니까?


14

우선 순위 큐라고도 하는 은 추상 데이터 유형입니다. 개념적으로, 이것은 모든 노드의 자식이 노드 자체보다 작거나 같은 이진 트리입니다. (최대 힙이라고 가정합니다.) 요소를 밀거나 튀어 나오면 힙이 다시 정렬되므로 가장 큰 요소가 다음으로 표시됩니다. 트리 또는 배열로 쉽게 구현할 수 있습니다.

수용하기로 선택한 경우 배열이 유효한 힙인지 확인해야합니다. 모든 요소의 자식이 요소 자체보다 작거나 같은 경우 배열은 힙 형식입니다. 다음 배열을 예로 들어 보겠습니다.

[90, 15, 10, 7, 12, 2]

실제로 이것은 배열 형태로 배열 된 이진 트리입니다. 모든 요소에 자식이 있기 때문입니다. 90에는 15와 10의 두 자녀가 있습니다.

       15, 10,
[(90),         7, 12, 2]

15에는 또한 7 세와 12 세의 자녀가 있습니다.

               7, 12,
[90, (15), 10,        2]

10 명의 자녀가 있습니다 :

                      2
[90, 15, (10), 7, 12,  ]

그리고 다음 요소는 공간이 없다는 것을 제외하고는 10의 자녀입니다. 배열이 충분히 길면 7, 12 및 2도 자식을 갖습니다. 다음은 힙의 다른 예입니다.

[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]

그리고 이전 배열이 만드는 트리의 시각화는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

이것이 명확하지 않은 경우를 대비하여 i 번째 요소의 자식을 얻는 명시 적 공식은 다음과 같습니다.

//0-indexing:
child1 = (i * 2) + 1
child2 = (i * 2) + 2

//1-indexing:
child1 = (i * 2)
child2 = (i * 2) + 1

비어 있지 않은 배열을 입력으로 가져 와서 배열이 힙 순서이면 정확한 값을 출력하고 그렇지 않으면 거짓 값을 출력해야합니다. 프로그램 / 함수가 예상하는 형식을 지정하는 한 0 인덱싱 된 힙이거나 1 인덱싱 된 힙일 수 있습니다. 모든 배열은 양의 정수만 포함한다고 가정 할 수 있습니다. 당신은 할 수있다힙 내장을 사용할 없습니다 . 여기에는 다음이 포함되지만 이에 국한되지 않습니다.

  • 배열이 힙 형태인지 판별하는 함수
  • 배열을 힙 또는 힙 형식으로 변환하는 함수
  • 배열을 입력으로 받아서 힙 데이터 구조를 반환하는 함수

이 파이썬 스크립트를 사용하여 배열이 힙 형태인지 아닌지를 확인할 수 있습니다 (0 인덱스 됨).

def is_heap(l):
    for head in range(0, len(l)):
        c1, c2 = head * 2 + 1, head * 2 + 2
        if c1 < len(l) and l[head] < l[c1]:
            return False
        if c2 < len(l) and l[head] < l[c2]:
            return False

    return True

IO 테스트 :

이 모든 입력은 True를 반환해야합니다.

[90, 15, 10, 7, 12, 2]
[93, 15, 87, 7, 15, 5]
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[100, 19, 36, 17, 3, 25, 1, 2, 7]
[5, 5, 5, 5, 5, 5, 5, 5]

그리고이 모든 입력은 False를 반환해야합니다.

[4, 5, 5, 5, 5, 5, 5, 5]
[90, 15, 10, 7, 12, 11]
[1, 2, 3, 4, 5]
[4, 8, 15, 16, 23, 42]
[2, 1, 3]

평소와 같이, 이것은 코드 골프이므로 표준 허점이 적용되고 바이트 단위의 최단 답변이 이깁니다!



반복되는 요소가있는 경우이 정의에 따라 힙을 형성하는 것이 불가능할 수 있습니까?
feersum

@feersum 어떻 [3, 2, 1, 1]습니까?
Neil

@feersum 그것은 좋은 생각입니다, 나는 그것을 생각하지 못했습니다. 힙에 대한 설명을 업데이트하고 중복 요소가있는 예제를 추가했습니다. 감사합니다!
James

5
힙은 우선 순위 대기열이라고도하지 않습니다. 우선 순위 큐는 추상 데이터 유형입니다. 힙은 때때로 우선 순위 큐를 구현하는 데 사용되는 데이터 구조입니다. 우선 순위 대기열은 연결된 목록과 같은 다른 데이터 구조 위에 구현 될 수 있습니다.
Lyndon White

답변:


7

젤리, 11 9 5 바이트

x2:ḊṂ

Dennis 덕분에 4 바이트가 제거되었습니다!

여기에서 시도하십시오.

설명

x2          Duplicate each element.
:Ḋ          Each element divided by the input with the first element removed,
            as integer, so there is a 0 only if some element in the duplicated
            list is less than the corresponding element in the other.
            There are also elements left unchanged, but it doesn't matter as
            the input is all positive.
Ṃ           Minimum in the list.

10

자바 스크립트 (ES6), 34 30 바이트

a=>!a.some((e,i)=>e>a[i-1>>1])

편집 : 사양 설명에 대한 코드 수정 비용은 1 바이트이므로 4 바이트를 저장하는 @ edc65 덕분입니다.


테스트 케이스 2 [93, 15, 87, 7, 15, 5]와 6에 실패 함[5, 5, 5, 5, 5, 5, 5, 5]
edc65

이것은 더 잘 작동하고 3 자 더 짧습니다a=>!a.some((e,i)=>e>a[i-1>>1])
edc65

1
@ edc65 답변을 작성한 후 해당 테스트 케이스가 추가되었습니다.
Neil


4

J, 24 바이트

*/@:<:]{~0}:@,<.@-:@i.@#

설명

*/@:<:]{~0}:@,<.@-:@i.@#  Input: s
                       #  Count of s
                    i.@   Create range [0, 1, ..., len(s)-1]
                 -:@      Halve each
              <.@         Floor each
         0   ,            Prepend a zero to it
          }:@             Remove the last value to get the parent indices of each
      ]                   Identity function to get s
       {~                 Take the values from s at the parent indices
    <:                    For each, 1 if it is less than or equal to its parent else 0
*/@:                      Reduce using multiplication and return

3

MATL , 13 12 바이트

ttf2/k)>~4L)

온라인으로 사용해보십시오!또는 모든 테스트 사례를 확인하십시오. .

배열이 비어 있지 않고 모든 항목이 0이 아닌 경우 배열은 진실입니다. 그렇지 않으면 거짓입니다. 여기에 몇 가지 예 입니다.

설명

t     % Take input implicitly. Duplicate
tf    % Duplicate and push indices of nonzero entries. This gives [1 2 ... n] where n
      % is input size
2/k   % Divide by 2 and round down
)     % Index into input. Gives array of parents, except for the first entry
>~    % True for entries of the input that don't exceed those in the array of parents
4L)   % Discard first entry

2

파이썬 2, 45 바이트

f=lambda l:l==[]or l[len(l)/2-1]/l.pop()*f(l)

Falsy의 경우 0을, Truthy의 경우 0이 아닙니다.

마지막 요소가 index의 부모보다 작거나 같은지 확인합니다 len(l)/2-1. 그런 다음 목록의 마지막 요소가 제거 된 상태에서 목록이 비워 질 때까지 동일한 항목이 True인지 확인하기 위해 반복합니다.


48 바이트 :

f=lambda l,i=1:l==l[:i]or l[~-i/2]/l[i]*f(l,i+1)

각 인덱스 i에서 요소가 최대 인덱스의 상위 요소인지 확인(i-1)/2 . 그렇지 않은 경우 층 나누기는 0을 생성합니다.

기본 케이스를 i/len(l)or같은 길이 로 제공합니다. 처음에는 압축을 시도했지만 더 긴 코드 (57 바이트)를 얻었습니다.

lambda l:all(map(lambda a,b,c:b<=a>=c,l,l[1::2],l[2::2]))

1

R, 97 88 82 바이트

잘만되면 나는 이것을 올바르게 이해했다. 이제 더 많은 바이트를 제거 할 수 있는지 확인하십시오. rbind를 버리고 sapply에 넣고 1 기반 벡터를 올바르게 처리하십시오.

명명되지 않은 함수로 구현

function(Y)all(sapply(1:length(Y),function(X)Y[X]>=Y[X*2]&Y[X]>=Y[X*2+1]),na.rm=T)

몇 가지 테스트 사례

> f=
+ function(Y)all(sapply(1:length(Y),function(X)Y[X]>=Y[X*2]&Y[X]>=Y[X*2+1]),na.rm=T)
> f(c(90, 15, 10, 7, 12, 2))
[1] TRUE
> f(c(93, 15, 87, 7, 15, 5))
[1] TRUE
> f(c(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
[1] TRUE
> f(c(5, 5, 5, 5, 5, 5, 5, 5))
[1] TRUE
> f(c(4, 5, 5, 5, 5, 5, 5, 5))
[1] FALSE
> f(c(90, 15, 10, 7, 12, 11))
[1] FALSE
> f(c(4, 8, 15, 16, 23, 42))
[1] FALSE

seq(Y)대신 사용할 수 있습니다 1:length(Y).
rturnbull




0

C ++ 14, 134105 바이트

#define M(d) (2*i+d<c.size()&&(c[i]<c[2*i+d]||f(c,2*i+d)==0))
int f(auto&c,int i=0){return!(M(1)||M(2));}

요구 c용기를지지 할 .operator[](int).size()같이std::vector<int> .

언 골프 드 :

int f(auto& c, int i=0) {
    if (2*i+1<c.size() && c[i] < c[2*i+1]) return 0;
    if (2*i+2<c.size() && c[i] < c[2*i+2]) return 0;
    if (2*i+1<c.size() && (f(c,2*i+1) == 0)) return 0;
    if (2*i+2<c.size() && (f(c,2*i+2) == 0)) return 0;
    return 1;
}

진실 = 0및 거짓 = 1이 허용되는 경우 더 작을 수 있습니다 .


0

R, 72 바이트

다른 R 답변과 약간 다른 접근법 .

x=scan();all(diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)<1,na.rm=T)

stdin에서 입력을 읽고 모든 비교 쌍으로 구성된 벡터를 생성하고 서로 빼고 결과가 음수인지 또는 0인지 확인합니다.

설명

stdin에서 입력을 읽습니다.

x=scan();

쌍을 만드십시오. 부모 노드에 대한 색인을 만듭니다 1...N(여기서 N길이는 x). 우리는 각 부모가 (최대) 두 자녀를 가지고 있기 때문에 이것을 두 번 가져갑니다. 우리는 또한 아이들을, (1...N)*2그리고 (1...N)*2+1. 길이를 초과하는 인덱스의 x경우 R은 NA``사용할 수 없음 ''을 반환합니다 . 입력 90 15 10 7 12 2을 위해이 코드는 우리에게 제공합니다 90 15 10 7 12 2 90 15 10 7 12 2 15 7 2 NA NA NA 10 12 NA NA NA NA.

                  x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)]

이 쌍의 벡터에서, 각 요소는 N*2멀리 떨어져 파트너가 있습니다. 예를 들어 항목 1의 파트너는 위치 12 (6 * 2)에 있습니다. 우리 는 아이템을 올바른 파트너와 비교하도록 diff지정 lag=N*2하여 이러한 쌍 간의 차이를 계산하는 데 사용 합니다 . NA요소 에 대한 모든 작업은 단순히 반환 NA합니다.

             diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)

마지막으로, 우리는 반환 된 모든 값이 고려에서 값을 1제외하고 (즉, 첫 번째 숫자 인 부모가 두 번째 숫자 인 자식보다 큰지) 확인합니다 NA.

         all(diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)<1,na.rm=T)

0

사실은 16 바이트

이 답변은 주로 jimmy23013의 Jelly 답변을 합니다. 골프 제안을 환영합니다! 온라인으로 사용해보십시오!

;;2╟┬Σ1(tZ`i<`Mm

언 골핑

         Implicit input a.
;;       Duplicate a twice.
2╟       Wrap two of the duplicates into a list.
┬        Transpose the duplicates.
Σ        Sum all of the columns to get a flat list like this:
           [a_0, a_0, a_1, a_1, ..., a_n, a_n]
         This gets the parent nodes of the heap.
1(t      Get a[1:] using the remaining duplicate of a.
         This is a list of the child nodes of the heap.
Z`i<`M   Check if every child node is less than its parent node.
m        Get the minimum. This returns 1 if a is a max-heap, else 0.
         Implicit return.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.