**d -ary heap**  یا  **d-heap** یک ساختمان داده صف اولویت دار است، یک کلیت از یک هیپ دودویی که گره‌ها به جای دو فرزند *d* فرزند دارند. بنابراین هیپ دودویی یک هیپ ـ 2 است. طبق گفته‌های Tarjan و Jensen و همکارانشان  ، هیپ *d* تایی توسط Donald B. Hohnson در سال 1975 ابداع شده‌است.

این ساختمان داده به عملیات‌های با اولویت کمتر اجازه می دهد تا سریع تر از هیپ دودویی عمل کنند، با هزینه کندتر حذف کردن کمترین عملیات ها. این موازنه منجر به بهتر اجرا شدن الگوریتم‌هایی مثل الگوریتم دیکسترا که در آن کاهش عملیات‌های اولویت دار شایع تر از حذف حداقل عملیات‌ها است، شده‌است. علاوه بر این، هیپ *d* تایی بهتر از هیپ دودویی از حافظه نهان استفاده می‌کنند، و در عمل به آن‌ها اجازه می‌دهد تا سریع تر اجرا شوند با اینکه در تئوری بدترین سرعت اجرای بیشتری دارند.
همانند هیپ دودویی، هیپ‌های *d* تایی الگوریتم درجا هستند که از هیچ فضای ذخیره‌سازی اضافه‌ای فراتر از آنچه که برای ذخیره اعضای آرایه در هیپ نیاز است، استفاده نمی‌کنند.
همانند مبنای 2، هیپ *d*تایی هم یک ساختار اطلاعاتی درونی است که هیچ حافظه ی جانبی را فراتر از آنچه که نیاز دارد تا اعداد یک مبنا را ذخیره کند استفاده و اشغال نمی‌کند.

ساختمان داده
------------

هیپ *d*تایی شامل آرایه *n* عضوی است، که هر کدام از آن‌ها دارای اولویت در ارتباط با آن است. این اعضا ممکن است به عنوان گره‌هایی در یک درخت *d*تایی کامل که در جستجوی سطح اول ذکر شده، دیده شوند. عضوی که در جایگاه 0 آرایه قرار دارد، ریشه درخت را تشکیل می دهد، و اعضایی که در موقعیت {\displaystyle 1-d} آرایه قرار دارند، فرزندان ریشه و {\displaystyle d^{2}} عضو بعدی، نوه‌های آن هستند، و.... بنابراین، پدر عضوی که در مکان *i* است، (برای هر *i*> 0 ) عضوی است که در مکان کف 
{\displaystyle {((1-i)/d)}} ‎است و فرزندان آن اعضایی هستند که در مکان id + 1 تا id + d قرار دارند. با توجه به ویژگی هیپ در مین هیپ هر عضو یک اولویت دارد که حداقل به بزرگی پدرش است؛ در ماکس هیپ، هر عضو دارای اولولیتی حداکثر برابر پدرش است.

عضو دارای اولویت کمتر در مین هیپ (یا عضو دارای بیشترین اولویت در ماکس هیپ) همیشه در مکان صفر آرایه قرار می‌گیرد. برای حذف این عضو از صف اولویت، آخرین عضو *x* آرایه جای آن را می‌گیرد، و سایز آرایه یکی کم می‌شود. سپس، در صورتی که عضو *x* و فرزندانش خاصیت‌های هیپ را برآورده نکنند، *x* با یکی از فرزندانش جابجا می‌شود. (در مین هیپ عضوی که دارای کمترین اولویت است، یا در ماکس هیپ عضو دارای بیشترین اولویت). آن را با اعضای پایین‌تر در درخت و عضوهای بعدی در آرایه جابجا می کنیم، تا جایی که سرانجام خاصیت‌های هیپ برآورده بشود. همانند فرایند جابجایی رو به پایین، برای افزایش اولویت هر عضو در مین هیپ یا کاهش اولویت هر عضو در ماکس هیپ استفاده می‌شود.

برای وارد کردن عضو جدید به هیپ، عضو به آخر آرایه اضافه می‌شود و سپس در صورتی‌که خاصیت‌های هیپ نقض شده باشد، آن عضو با پدرش جابجا می‌شود. آن را در درخت به بالا انتقال داده و در آرایه به عضوهای اولیه منتقل می کنیم، تا جایی که خاصیت‌های هیپ برآورده بشود. همانند فرایند جابجایی رو به بالا، برای کاهش اولویت هر عضو در مین هیپ یا افزایش اولویت هر عضو در ماکس هیپ استفاده می‌شود.

برای ایجاد یک هیپ جدید از آرایه *n* عضوی، ممکن است یک حلقه در جهت معکوس ایجاد شود. این حلقه از عضوی با مکان {\displaystyle } شروع شده و به عضو در مکان صفر ختم می‌شود. فرایند جابجایی رو به پایین برای هر عضو اجرا می‌شود.

تجزیه و تحلیل
-------------

در هیپ *d* تایی با داشتن *n* عضو، هر دو فرایند جابجایی رو به بالا و فرایند جابجایی رو به پایین به تعداد 
{\displaystyle {1-n}} ‎ جابجایی وجود دارد. در فرایند جابجایی رو به بالا، هر تعویض شامل تنها یک مقایسه هر عضو با پدرش است و یک زمان ثابت طول می کشد. بنابراین، زمان وارد کردن یک عضو جدید در هیپ، کاهش اولویت یک عضو در مین هیپ، یا افزایش اولویت یک عضو در ماکس هیپ {\displaystyle {dgol/ngol=n\_{d}gol}} می‌باشد. در فرایند جابجایی رو به پایین، هر تعویض شامل *d* مقایسه است و (*d*)O زمان لازم دارد. 1 – *d* مقایسه لازم است تا کوچکترین و بزرگترین فرزند تعیین شود و سپس یک مقایسه دیگر با پدر تا تعیین شود که آیا تعویض نیاز است یا نه. بنابراین، زمان حذف کردن عضو ریشه، افزایش اولویت هر عضو در مین هیپ، یا کاهش اولویت هر عضو در ماکس هیپ، {\displaystyle {(dgol/ngol)O}} می‌باشد.

وقتی یک هیپ *d* تایی از *n* عضو ساخته می‌شود، بیشتر اعضا در مکانی قرار دارند که سرانجام برگ‌های درخت *d* تایی را تشکیل می دهند و جابجایی رو به پایین برای آن‌ها صورت نمی‌گیرد. در حداکثر {\displaystyle {(dgol/ngold)O}} ‎ از اعضا، که برگ نیستند حداقل یک بار جابجایی رو به پایین با هزینه زمانی (*d*)O برای یافتن فرزند برای جابجایی با آن صورت می‌گیرد. در حداکثر {\displaystyle {1+d/n}} ‎ گره ممکن است جابجایی رو به پایین دو بار صورت بگیرد، که در این صورت (*d*)O هزینه اضافی برای دومین جابجایی، فراتر از هزینه‌ای که برای دوره اول محاسبه شده بود، نیاز است و... 
بنابراین، مقدار کل زمانی که برای ساختن یک هیپ با این روش نیاز است برابر است با:

```
 {\displaystyle {1+^{2}d/n}}  
```

فضای استفاده شده توسط هیپ *d* تایی با عملیات‌های درج و حذف کوچکترین عضو خطی است، به‌طوری‌که نسبت به آرایه‌های دیگری که شامل لیستی از اعضا در هیپ هستند، از فضای ذخیره‌سازی اضافی استفاده نمی‌کند. اگر تغییراتی در اولویت‌های اعضای موجود نیاز باشد، یکی از اعضا باید اشاره گرهایی که فقط فضای ذخیره‌سازی خطی دوباره از آن‌ها استفاده می‌کند را از اعضا به مکانشان در هیپ نگه دارد.

کاربردها
--------

الگوریتم دیکسترا برای یافتن کوتاهترین مسیر در گراف‌ها و الگوریتم پریم برای درخت فراگیر مینیمم، هر دو از مین هیپ استفاده می‌کنند که در آن *n* عملیات حذف مینیمم و *m* عملیات کاهش اولویت وجود دارد. که *n* تعداد رئوس در گراف و *m* تعداد یال‌ها است. با استفاده از یک هیپ *d* تایی با {\displaystyle \sum \_{i=1}^{\log \_{d}n}\left({\frac {n}{d^{i}}}+1\right)O(d)=O(n).} ‎ کل زمان برای این دو نوع عملیات ممکن است متعادل شود که کل زمان برای الگوریتم برابر می‌شود با {\displaystyle {n/m=d}} ‎. زمان اجرای بهبود یافته هیپ دودویی این الگوریتم‌ها وقتی که تعداد یال‌ها به‌طور قابل ملاحظه‌ای بیشتر از تعداد رأس‌ها باشد، برابر است با {\displaystyle {(n\_{n/m}golm)O}}. یک ساختمان داده صف اولویت دیگر، هیپ فیبوناتچی است که زمان اجرای نظری بهتر {\displaystyle {(ngolm)O}} را می‌دهد. ولی در عمل، به‌طور کلی هیپ *d*تایی‌ها حداقل به همان اندازه سریع یا اغلب سریع تر از هیپ فیبونانچی برای این کاربرد هستند.

4-هیپ‌ها در عمل ممکن است عملکرد بهتری حتی در عملیات‌های حذف مینیمم نسبت به هیپ دودویی داشته باشند. علاوه بر این، معمولاً هیپ‌های *d*تایی بسیار سریع تر از هیپ دودویی اجرا می‌شود. به خاطر اندازه هیپ که بیشتر از اندازه حافظه نهان کامپیوتر است. هیپ دودویی معمولاً به کش سی‌پی‌یو بیشتر و page fault حافظه مجازی بیشتری نسبت به هیپ *d*تایی نیاز دارد.

| * ن
* ب
* و
ساختمان داده‌ها |
| --- |
| انتزاعی | 
* آرایه انجمنی
* پشته
* صف
	+ دوطرفه
* صف اولویت
	+ دوطرفه
* لیست
* مجموعه
	+ مجزا

 |
| آرایه‌ها | 
* آرایه بیتی
* آرایه پویا
* جدول درهم‌سازی
* درخت آرایه درهم
* بافر چرخشی
* ماتریس خلوت

 |
| پیوندی | 
* فهرست انجمنی
* فهرست پرشی
* فهرست پیوندی
	+ دوطرفه
	+ واپیچیده
	+ XOR

 |
| درخت | 
* درخت جستجوی دودویی (AVL •  قرمز-سیاه •  اسپلی)
* بی
* بی‌پلاس
* هیپ (دی هیپ •  فیبوناتچی •  دوجمله‌ای)
* فنویک
* ترای

 |
| گراف | 
* جهت‌دار
* جهت‌دار بدون‌دور
* ابرگراف

 |

منابع
-----

1. 1 2 3 4 5 6 7 8 9 10 11  Tarjan, R. E. (1983), "3.2. *d*-heaps", *Data Structures and Network Algorithms*, CBMS-NSF Regional Conference Series in Applied Mathematics, vol. 44, Society for Industrial and Applied Mathematics, pp. 34–38.
2. 1 2 3 4 5 6 7 8  Weiss, M. A. (2007), "*d*-heaps", *Data Structures and Algorithm Analysis* (2nd ed.), Addison-Wesley, p. 216, ISBN 0321370139.
3. ↑  Jensen, C.; Katajainen, J.; Vitale, F. (2004), *An extended truth about heaps* (PDF), archived from the original (PDF) on 9 June 2007, retrieved 25 February 2012.
4. 1 2 3  Johnson, D. B. (1975), "Priority queues with update and finding minimum spanning trees", *Information Processing Letters*, **4** (3): 53–57, doi:10.1016/0020-0190(75)90001-0.
5. 1 2  (Tarjan 1983), pp. 77 and 91.
6. 1 2  Mortensen, C. W.; Pettie, S. (2005), "The complexity of implicit and space efficient priority queues", *Algorithms and Data Structures: 9th International Workshop, WADS 2005, Waterloo, Canada, August 15-17, 2005, Proceedings*, Lecture Notes in Computer Science, vol. 3608, Springer-Verlag, pp. 49–60, doi:10.1007/11534273\_6, ISBN 978-3-540-28101-6.
7. ↑  Cherkassky, B. V.; Goldberg, A. V.; Radzik, T. (1996), "Shortest paths algorithms: Theory and experimental evaluation", *Mathematical Programming*, **73** (2): 129–174, doi:10.1007/BF02592101.
8. ↑  Naor, D.; Martel, C. U.; Matloff, N. S. (1991), "Performance of priority queue structures in a virtual memory environment", *Computer Journal*, **34** (5): 428–437, doi:10.1093/comjnl/34.5.428.
9. ↑  Kamp, Poul-Henning (2010), "You're doing it wrong", *ACM Queue*, **8** (6).

پیوند به بیرون
--------------

* C++ implementation of generalized heap with D-Heap support

|  |  |
| --- | --- |
|  | در ویکی‌انبار پرونده‌هایی دربارهٔ هرم دی‌تایی موجود است. |