Heapify the Heap (Heap-ի վերականգնում)

Heap-ում կարելի է կատարել երկու հիմնական գործողություն. կարելի է նոր տարր ավելացնել և կարելի է հեռացնել heap-ի արմատային հանգույցը:
Յուրաքանչյուր գործողությունից հետո անհրաժեշտ է համոզվել, որ heap-ի հատկությունները չեն խախտվել:
Երբ հեռացնում ենք արմատը, պետք է բարձրից հասնել մինչև heap-ի վերջին աստիճան՝ անհրաժեշտ փոփոխություններ կատարելով և վերականգնելով այն, որպեսզի ծնող հանգույցների արժեքները ավելի մեծ լինեն, քան երեխաների արժեքները (max-heap-ի դեպքում):
8 հանգույցներով max-heap-ի օրինակ
8 հանգույցներով max-heap-ի օրինակ
Երբ նոր տարր ենք ավելացնում, անհրաժեշտ է սկսել heap-ի ամենաստորին մասից և բարձրանալ վեր՝ այնպես վերակազմակերպելով կառուցվածքը, որ ծնող հանգույցների արժեքները մեծ լինեն երեխաների արժեքներից:

Insert a New Element Into a Heap

Heap-ում նոր արժեք ավելացնելու համար սկզբում ավելացվում է արժեքը զանգվածի վերջում, ապա heap-ի հատկությունը վերականգնվում է. նոր տարրը անհրաժեշտության դեպքում շարունակաբար փոխանակվում է իր ծնողի հետ, եթե խախտվում է ծնողի և երեխայի արժեքների միջև եղած պահանջը:
heap = [None, 8, 5, 7, 1, 1, 6, 3, 1] # նախնական heap
heap.append(6)                        # Ավելացնել նոր տարր արժեքով 6

# Բարձրանալ վեր և շտկել heap-ի հատկությունները
node = len(heap) - 1                  # Ընթացիկ հանգույցի ինդեքսը
while node > 1:                       # Մինչև չհասնենք արմատին
    parent = node // 2                # Ստանալ ծնող հանգույցի ինդեքսը
    if heap[node] > heap[parent]:     # Եթե heap-ի կառուցվածքը ճիշտ չէ
        heap[node], heap[parent] = heap[parent], heap[node]
    else:                             # Եթե կառուցվածքը ճիշտ է
        break                         # Ուրեմն վերևում գտնվողներն էլ են տեղին => դադարեցրու
    node //= 2                        # Անցնել ծնող հանգույցին

Delete the Root Element of a Heap

Heap-ի արմատային տարրը հեռացնելու համար այն նախ փոխանակվում է զանգվածի վերջին տարրի հետ, ապա heap-ի հատկությունը վերականգնվում է. փոխանակված տարրը շարունակաբար փոխվում է իր ամենամեծ երեխայի հետ (max-heap-ի դեպքում), մինչև հայտնվի ճիշտ դիրքում:
heap = [None, 8, 5, 7, 1, 1, 6, 3, 1] # նախնական heap
heap[1], heap[-1] = heap[-1], heap[1] # Արմատը փոխանակել վերջին տարրի հետ
heap.pop()                            # Ջնջել վերջին տարրը (նախկին արմատը)

# Իջնել ներքև և շտկել heap-ի հատկությունները
node = 1                              # Ընթացիկ հանգույցի ինդեքսը
while node < len(heap):               # Մինչև չհասնենք ավարտին
    left = heap[2 * node] if 2 * node < len(heap) else float('-inf')
    right = heap[2 * node + 1] if 2 * node + 1 < len(heap) else float('-inf')
    
    # Եթե heap-ի հատկությունը չի խախտված => կանգ առեք
    if heap[node] >= left and heap[node] >= right:
        break
    
    # Եթե left > right => պետք է անցնել ձախ ուղղությամբ
    if left > right:
        heap[2 * node], heap[node] = heap[node], heap[2 * node]
        node = 2 * node
    else:
        heap[2 * node + 1], heap[node] = heap[node], heap[2 * node + 1]
        node = 2 * node + 1

Առաջադրանք: Fix the Heap

Տրված է min-heap (մին-heap) n թվերով, որտեղ n-1 թվերը բավարարում են min-heap-ի հատկությունը, իսկ n-րդ թիվը հնարավոր է խախտի այդ հատկությունը: Ձեր խնդիրն է վերականգնել heap-ը, zodat որ բոլոր թվերը կրկին բավարարեն min-heap-ի հատկությունը:

Մուտք

Մուտքի առաջին տողում տրված է n ամբողջ թիվը (1 ≤ n ≤ ).
Հաջորդ տողում կան n ամբողջ թվեր (), որոնք heap-ի տարրերի արժեքներն են:

Ելք

Ծրագիրը պետք է տպի n ամբողջ թվեր, որոնք բաժանված են բացատներով և ներկայացնում են շտկված heap-ը:

Օրինակներ

Մուտք
Ելք
7 1 2 5 4 3 6 -3
-3 2 1 4 3 6 5
6 5 6 9 20 10 8
5 6 8 20 10 9

Բացատրություն

Օրինակ 1
notion image
 
Օրինակ 2
notion image
 

Constraints

Time limit: 5 seconds

Memory limit: 512 MB

Output limit: 10 MB

To check your solution you need to sign in
Sign in to continue