هرم جفتشده
یک هرم جفت شده یک نوع داده ساختار هیپ با پیادهسازی نسبتاً ساده و عملکرد سرشکن شدهٔ عالی معرفی شده توسط Micheal Fredman، Robert Sedgewick، Daniel Sleator و Robert Tarjan در سال ۱۹۸۶ میباشد. هرمهای جفت شده ساختمانهای درختی چند راهه میباشند که مانند هرم مرتب شدهاند و میتوانند هرمهای فیبوناچی ساده شده در نظر گرفته شوند. آنها انتخابات قوی برای پیادهسازی الگوریتمهایی مانند الگوریتم پریم در نظر گرفته میشوند و از توابع زیر پیروی میکنند (با فرض اینکه مین-هیپ باشند):
- پیدا کردن کمینه: به سادگی به آیتم بالای هرم برمیگردیم.
- ادغام: دو ریشه را با یک دیگر مقایسه میکنیم ریشهٔ کوچکتر ریشهٔ اصلی میشود و ریشهٔ بزرگتر و زیردرخت آن فرزند این ریشهٔ اصلی میشوند.
- درج: یک هرم برای عنصر درج شده ساخته و آن را با هرم اصلی ادغام میکنیم.
- کاهش کلید (اختیاری): زیرهرمی که ریشه اش این کلید است را حذف میکنیم کلید را با یک کلید کوچکتر جایگزین میکنیم سپس نتیجه را دوباره با هرم اصلی ادغام میکنیم.
- حذف مینیمم: ریشه را حذف کرده و زیرهرمهایش را با یکدیگر ادغام میکنیم. استراتژیهای مختلفی به کار گرفته میشوند.
تحلیل پیچیدگی زمانی هرمهای جفت شده ابتدا از درختان اسپلی الهام گرفته شده بود. اوردر سرشکن شدهٔ هر حذف کمینه O(log n) است و عملیات پیدا کردن حداقل، ادغام و درج در سرشکن شدهٔ O(1) انجام میگیرد.
تعیین زمان دقیق مجانبی هرمهای جفت شده زمانی که یک عملیات کاهش کلید نیاز است کمی دشوار میباشد. در ابتدا به صورت تجربی حدس میزدند که زمان پیچیدگی این عملیات O(1) باشد
اما Fredman ثابت کرد که زمان سرشکن هر کاهش کلید برای توالی برخی عملیات حداقل
اگر چه این بدتر از دیگر الگوریتمهای صف اولویت مانند هیپ فیبوناچی است که انجام کاهش کلیدشان در سرشکن
ساختار
یک هرم جفت شده یا یک هرم خالی است یا یک جفت متشکل از یک ریشه و احتمالاً یک لیست خالی از هرمهای جفت شده. برای ویژگی ترتیب هرمها نیاز است که ریشه هیچکدام از زیرهرمهای این هرم کوچکتر از ریشهٔ خود هرم نباشند. این توصیف صرفاً یک هرم تابعی را میدهد که از کاهش کلید پشتیبانی نمیکند.
type PairingHeap[Elem] = Empty | Heap(elem: Elem, subheaps: List[PairingHeap[Elem]])
یک پیادهسازی بر اساس اشاره گر برای ماشینهای رم میتوان ارائه داد که از کاهش کلید پشتیبانی میکند. این پیادهسازی در هر گره سه اشاره گر دارد: یکی به اولین فرزندش، یکی به برادرش و یکی به پدرش. همچنین اشاره به پدر میتواند حذف شود اگر برگها به جای فرزند به ریشه اشاره کنند و یک پرچم برای برگها گذاشته شود تا تشخیص داده شوند؛ که این یک ساختار جمع و جور تر است با همان سربار قبلی.
عملیاتها
پیدا کردن مینیمم
تابع پیدا کردن مینیمم فقط ریشهٔ هرم را برمیگرداند:
function find-min(heap)
if heap == Empty error else return heap.elem
ادغام
ادغام با یک هرم خالی هرم اول را برمیگرداند در غیر این صورت یک هرم جدید برگردانده میشود که ریشهٔ کوچکتر ریشهٔ آن بوده و هرم با ریشهٔ بزرگتر به فرزندان آن اضافه میشود:
function merge(heap1, heap2)
if heap1 == Empty return heap2 elsif heap2 == Empty return heap1 elsif heap1.elem < heap2.elem return Heap(heap1.elem, heap2 :: heap1.subheaps) else return Heap(heap2.elem, heap1 :: heap2.subheaps)
درج
سادهترین راه برای درج یک آیتم در یک هرم این است که هرم اصلی را با یک هرم که فقط عنصر درج شده در آن قرار دارد ادغام کنیم:
function insert(elem, heap)
return merge(Heap(elem, []), heap)
حذف
تنها عمل اساس غیر بدیهی در هرم حذف عنصر مینیمم از هرم میباشد. استراتژی استاندارد اول زیردرختها را ادغام میکند (نام گذاری این ساختمان داده به خاطر این مرحله میباشد) از چپ به راست و سپس لیست هیپهای نتیجه شده را از راست به چپ ادغام میکند:
function delete-min(heap)
if heap == Empty error else return merge-pairs(heap.subheaps)
که این از تابع کمکی merge-pairs استفاده میکند:
function merge-pairs(l)
if length(l) == ۰ return Empty elsif length(l) == ۱ return l[0] else return merge(merge(l[0], l[1]), merge-pairs(l[2.. ]))
که این در واقع ادغام دو طرفه چپ به راست و راست به چپ را پیادهسازی میکند:
merge-pairs([H1, H2, H3, H4, H5, H6, H7])
=> merge(merge(H1, H2), merge-pairs([H3, H4, H5, H6, H7])) # merge H1 and H2 to H12, then the rest of the list => merge(H12, merge(merge(H3, H4), merge-pairs([H5, H6, H7]))) # merge H3 and H4 to H34, then the rest of the list => merge(H12, merge(H34, merge(merge(H5, H6), merge-pairs([H7])))) # merge H5 and H6 to H56, then the rest of the list => merge(H12, merge(H34, merge(H56, H7))) # switch direction, merge the last two resulting heaps, giving H567 => merge(H12, merge(H34, H567)) # merge the last two resulting heaps, giving H34567 => merge(H12, H34567) # finally, merge the first merged pair with the result of merging the rest => H1234567
منابع
- ↑ Fredman, Michael L.; Sedgewick, Robert; Sleator, Daniel D.; Tarjan, Robert E. (1986). "The pairing heap: a new form of self-adjusting heap" (PDF). Algorithmica. 1 (1): 111–129. doi:10.1007/BF01840439.
- ↑ Mehlhorn, Kurt; Sanders, Peter (2008). Algorithms and Data Structures: The Basic Toolbox (PDF). Springer. p. 231.
- ↑ Iacono, John (2000). Improved upper bounds for pairing heaps (PDF). Proc. 7th Scandinavian Workshop on Algorithm Theory. Lecture Notes in Computer Science. Vol. 1851. Springer-Verlag. pp. 63–77. arXiv:1110.4428. doi:10.1007/3-540-44985-X_5. ISBN 978-3-540-67690-4. Archived from the original (PDF) on 24 December 2012. Retrieved 6 May 2016.
- ↑ Stasko, John T.; Vitter, Jeffrey S. (1987), "Pairing heaps: experiments and analysis", Communications of the ACM, 30 (3): 234–249, doi:10.1145/214748.214759, CiteSeerX: 10.1.1.106.2988
- ↑ Fredman, Michael L. (1999). "On the efficiency of pairing heaps and related data structures" (PDF). Journal of the ACM. 46 (4): 473–501. doi:10.1145/320211.320214. Archived from the original (PDF) on 21 July 2011. Retrieved 6 May 2016.
- ↑ Pettie, Seth (2005), "Towards a final analysis of pairing heaps" (PDF), Proc. 46th Annual IEEE Symposium on Foundations of Computer Science, pp. 174–183, doi:10.1109/SFCS.2005.75, ISBN 0-7695-2468-0
- ↑ Elmasry, Amr (2009), "Pairing heaps with decrease cost" (PDF), Proc. 20th Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 471–476, doi:10.1137/1.9781611973068.52, archived from the original (PDF) on 18 اكتبر 2012, retrieved 6 May 2016
- ↑ Larkin, Daniel H.; Sen, Siddhartha; Tarjan, Robert E. (2014), "A back-to-basics empirical study of priority queues", Proceedings of the 16th Workshop on Algorithm Engineering and Experiments, pp. 61–72, arXiv:1403.0252, doi:10.1137/1.9781611973198.7
- ↑ Moret, Bernard M. E.; Shapiro, Henry D. (1991), "An empirical analysis of algorithms for constructing a minimum spanning tree", Proc. 2nd Workshop on Algorithms and Data Structures, Lecture Notes in Computer Science, vol. 519, Springer-Verlag, pp. 400–411, doi:10.1007/BFb0028279, ISBN 3-540-54343-0, CiteSeerX: 10.1.1.53.5960