Проблема накопичувальної купи із CLRS


10

Я розгубився, вирішуючи наступну проблему (питання 1-3).

Питання

Д -ічние куп, як виконавчі купи, але (з одним можливим винятком) вузли без листя мають d дітей замість 2 -х дітей.

  1. Як би ви представляли d -ary купу в масиві?

  2. Яка висота d -аричної маси n елементів у перерахунку на n та d ?

  3. Надайте ефективну реалізацію EXTRACT-MAX у максимізованій купі d -ary. Проаналізуйте його час роботи з точки зору d і n .

  4. Дайте ефективну реалізацію вставки в г -ічний макс купи. Проаналізуйте його час роботи з точки зору d і n .

  5. Дайте ефективну реалізацію INCREASE-KEY ( A , i , k ), яка позначає помилку, якщо k <A [i] = k, а потім належним чином оновлює структуру купи матриці d -ary. Проаналізуйте його час роботи з точки зору d і n .

Моє рішення

  1. Надати масивA[a1..an]

    root:a1level 1:a2a2+d1level 2:a2+da2+d+d21level k:a2+i=1k1dia2+i=1kdi1

    Моє позначення здається дещо складним. Чи є інший простіший?

  2. Нехай h позначає висоту кучі d -ary.

    Припустимо, що купа - це повне d -ary дерево

    1+d+d2+..+dh=ndh+11d1=nh=logd[nd1+1]1
  3. Це моя реалізація:

    EXTRACT-MAX(A)
    1  if A.heapsize < 1
    2      error "heap underflow"
    3  max = A[1]
    4  A[1] = A[A.heapsize]
    5  A.heap-size = A.heap-size - 1
    6  MAX-HEAPIFY(A, 1)
    7  return max
    
    MAX-HEAPIFY(A, i)
    1  assign depthk-children to AUX[1..d]
    2  for k=1 to d
    3      compare A[i] with AUX[k]
    4      if A[i] <= AUX[k]
    5          exchange A[i] with AUX[k]
    6          k = largest
    7  assign AUX[1..d] back to A[depthk-children]
    8  if largest != i
    9      MAX-HEAPIFY(A, (2+(1+d+d^2+..+d^{k-1})+(largest-1) )
    
    • Час роботи MAX-HEAPIFY:

      TM=d(c8d+(c9+..+c13)d+c14d)
      де позначає вартість i -го рядка вище.ci
    • ЕКСТРАКТ-МАКС:

      TE=(c1+..+c7)+TMCdh=Cd(logd[n(d1)+1]1)=O(dlogd[n(d1)])

    Це ефективне рішення? Або в моєму рішенні щось не так?


Я думаю, що в питанні, а також у поясненні, є невелика помилка: Висота купи d-ary доходить до h = (log [nd - n + 1]) - 1 // ВКАЗАТИ своє "-n", а не "-1" і не. h = (log [nd−1+1])− 1Отже, вище пояснення висоти не буде правдивим. h = log [nd − 1 + 1] −1 = log [nd] -1 = log [n] Хоча, тим не менше, висота дерева записується як Θ(log(n)).Примітка: журнал завжди знаходиться до основи d для д-арної купи .
Сурабхі Радже

Відповіді:


10
  1. Ваше рішення є дійсним і відповідає визначенню d -ary купи. Але, як ви зазначали, ваша нотація є дещо складною.

    Ви можете використовувати ці дві наступні функції для отримання батьківського елемента i -го елемента та j -го дочірнього i -го елемента.

    d-ary-parent(i)    return (i2)/d+1

    d-ary-child(i,j)    return d(i1)+j+1

    Очевидно . Ви можете перевірити ці функції, перевіривши, що1jdd-ary-parent(d-ary-child(i,j))=i

    Також легко помітити те, що двійкова купа - це особливий тип -ary купи, де , якщо ви заміните на , то ви побачите, що вони відповідають функціям РОБІТЬ, ЛІВО та ВПРАВО, згадані в книзі.dd=2d2

  2. Якщо я правильно зрозумів вашу відповідь, ви використовуєте геометричну прогресію . У вашому випадку ви отримаєте , що, очевидно, , що насправді є правильним і правильним рішенням. Але тільки для управління постійними коливаннями ви можете хотіти писати .h=logd(nd1+1)1logd(nd)1=logd(n)+logd(d)1=logd(n)+11=logd(n)Θ(logd(n))

    Причиною цього є те, що деякі купи можуть не бути врівноваженими, тому їх найдовший шлях та найкоротший міг змінюється залежно від постійної , використовуючи позначення ви усунете цю проблему.cΘ

  3. Вам не потрібно повторно реалізовувати процедуру, подану в підручнику, але її потрібно трохи змінити, наприклад, призначити всіх дітей таблиці за допомогою заданих та функції.AUXd-ary-parentd-ary-child

    Оскільки не змінено, це залежить від часу запуску . Тепер у своєму аналізі ви повинні використовувати найгірший час, пропорційний висоті та кількості дітей, які повинен перевірити кожен вузол (щонайбільше d ). Ще раз ваш аналіз дуже точний, врешті-решт ви отримали , який можна перетворити на:EXTRACT-MAXMAX-HEAPIFYO(d logd(n(d1)))

    O(d logd(n(d1)))=O(d(logd(n)+log(d1)))=O(d logd(n)+d logd(d1))

    З практичних причин , ми завжди можемо вважати , що , так що ми можемо втратити частину O нотації, то ми отримаємо . Що також є правильним рішенням. Але не дивно, що ви також можете проаналізувати час виконання функції, використовуючи теорему , яка покаже, що є не тільки але навіть .dndlogd(d1)O(dlogd(n))MAX-HEAPIFYOΘ

  4. У книзі CLRS вже передбачена процедура INSERT. Як виглядає так:

    INSERT(A,key)    A.heap_size=A.heap_size+1    A[A.heap_size]=    INCREASE-KEY(A,A.heap_size,key)

    Це можна легко довести, але здоровий глузд диктує, що час складності - це . Це тому, що купа може проходити аж до кореня.O(logd(n))

  5. Як і INSERT, INCREASE-KEY також визначається в підручнику як:

    INCREASE-KEY(A,i,key)    if key<A[i]        error"new key is smaller then current"    A[i]=key    while i>1 and A[i]>A[d-ary-parent(i)]        A[i]A[d-ary-parent(i)]        i=d-ary-parent(i)

    Складність, очевидно, (див. Попередній пункт).O(logd(n))


Дякую! Як щодо впровадження INCREASE-KEY та INSERT? Я намагаюся написати це, але він давав двічі рекурсивний дзвінок MAX-HEAPIFY. Чи є краще рішення? Я знайшов мало інформації в Інтернеті та вікі
lucasKo

Це решта вправ? Якщо так, будь ласка, оновіть своє запитання, і я з радістю відповім на тему.
Bartosz Przybylski

Я поставив це питання на відредагованій публікації.
lucasKo

реімпліментація процедури INSERT? Тобто, після вставлення нового елемента не потрібно викликати процедуру, яка коригує порядок усередині купи? Я не розумію ...
lucasKo

Цей опис трохи прикро, див. Редагування для очищення.
Bartosz Przybylski

1

Це не повна відповідь. частина б) рішення не Його як вказував користувач 55463 (тому що він не вміє коментувати, але відповідати), але прихильний через відсутність пояснень . Обґрунтована відповідь також помилково її вирішила. Відповідь все одно буде Джерело: Проблема 2-2. Аналіз d -ary купи, частина b)

h=logd[nd1+1]1
h = Θ ( log d ( n ) )
1+d+d2+..+dh=ndh+11d1=nh=logd[n(d1)+1]1
h=Θ(logd(n))

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.