आरंभीकरण वेक्टर का उपयोग करके व्यवहार को पुन: पेश किया जा सकता है [0, 1, 2, 4, 5, 3]
। परिणाम है:
[०, १, २, ४, ३, ५]
(हम देख सकते हैं कि 3 को गलत तरीके से रखा गया है)
Push
एल्गोरिथ्म सही है। यह एक सीधा तरीके से एक मिनट-ढेर बनाता है:
- नीचे से शुरू करो
- यदि मान मूल नोड से अधिक है, तो उसे डालें और वापस लौटें
- अन्यथा, माता-पिता के बजाय नीचे दाईं ओर रखें, फिर मूल स्थान पर मान डालने का प्रयास करें (और जब तक सही जगह न मिल जाए, तब तक पेड़ की अदला-बदली करते रहें)
परिणामी पेड़ है:
0
/ \
/ \
1 2
/ \ /
4 5 3
मुद्दा Pop
विधि के साथ है । इसे भरने के लिए शीर्ष नोड को "गैप" मानकर शुरू होता है (क्योंकि हमने इसे पॉप किया है):
*
/ \
/ \
1 2
/ \ /
4 5 3
इसे भरने के लिए, यह सबसे कम तात्कालिक बच्चे की खोज करता है (इस मामले में: 1)। इसके बाद अंतर को भरने के लिए मूल्य बढ़ जाता है (और बच्चा अब नया अंतर है):
1
/ \
/ \
* 2
/ \ /
4 5 3
यह फिर नए अंतर के साथ सटीक काम करता है, इसलिए अंतराल फिर से नीचे चला जाता है:
1
/ \
/ \
4 2
/ \ /
* 5 3
जब अंतर नीचे तक पहुंच गया है, तो एल्गोरिथ्म ... पेड़ के नीचे-सबसे सही मूल्य लेता है और अंतराल को भरने के लिए इसका उपयोग करता है:
1
/ \
/ \
4 2
/ \ /
3 5 *
अब यह अंतर सबसे निचले नोड पर है, यह _count
पेड़ से खाई को हटाने के लिए घटता है:
1
/ \
/ \
4 2
/ \
3 5
और हम अंत में ... एक टूटे हुए ढेर।
पूरी तरह से ईमानदार होने के लिए, मुझे समझ नहीं आता कि लेखक क्या करना चाह रहा था, इसलिए मैं मौजूदा कोड को ठीक नहीं कर सकता। अधिक से अधिक, मैं इसे एक कार्यशील संस्करण के साथ स्वैप कर सकता हूं (बेशर्मी से विकिपीडिया से कॉपी किया गया ):
internal void Pop2()
{
if (_count > 0)
{
_count--;
_heap[0] = _heap[_count];
Heapify(0);
}
}
internal void Heapify(int i)
{
int left = (2 * i) + 1;
int right = left + 1;
int smallest = i;
if (left <= _count && _comparer.Compare(_heap[left], _heap[smallest]) < 0)
{
smallest = left;
}
if (right <= _count && _comparer.Compare(_heap[right], _heap[smallest]) < 0)
{
smallest = right;
}
if (smallest != i)
{
var pivot = _heap[i];
_heap[i] = _heap[smallest];
_heap[smallest] = pivot;
Heapify(smallest);
}
}
उस कोड के साथ मुख्य मुद्दा पुनरावर्ती कार्यान्वयन है, जो तत्वों की संख्या बहुत बड़ी होने पर टूट जाएगा। मैं इसके बजाय एक अनुकूलित तीसरे पक्ष के पुस्तकालय का उपयोग करने की दृढ़ता से सलाह देता हूं।
संपादित करें: मुझे लगता है कि मुझे पता चला है कि क्या गायब है। निचले-दाएं नोड को लेने के बाद, लेखक ने ढेर को फिर से असंतुलित करना भूल गया:
internal void Pop()
{
Debug.Assert(_count != 0);
if (_count > 1)
{
int parent = 0;
int leftChild = HeapLeftChild(parent);
while (leftChild < _count)
{
int rightChild = HeapRightFromLeft(leftChild);
int bestChild =
(rightChild < _count && _comparer.Compare(_heap[rightChild], _heap[leftChild]) < 0) ?
rightChild : leftChild;
_heap[parent] = _heap[bestChild];
parent = bestChild;
leftChild = HeapLeftChild(parent);
}
_heap[parent] = _heap[_count - 1];
int index = parent;
var value = _heap[parent];
while (index > 0)
{
int parentIndex = HeapParent(index);
if (_comparer.Compare(value, _heap[parentIndex]) < 0)
{
var pivot = _heap[index];
_heap[index] = _heap[parentIndex];
_heap[parentIndex] = pivot;
index = parentIndex;
}
else
{
break;
}
}
}
_count--;
}