把
算法导论第六章的堆排序用C#实现了一下。 把MaxHeapify用迭代实现了。发现几个问题:
第一呢,算法导论中假设内部数组是从1开始的,结果左右结点的算法和从0开始的数组实际上是不同的。
第二呢,在改迭代的时候,粗心把循环变量写错了。结果调了很久,郁闷死。
并且加入优先级队列的功能,包括Maximum, ExtractMax, IncreaseKey, Insert, Delete子过程
下面是实现的代码:
namespace FengChen.Practices
...{
public class Chapter6
...{
public class MaxHeap
...{
private Int32[] m_Array;
private Int32 m_Size;
heap tree node navigation#region heap tree node navigation
internal static Int32 PARENT(Int32 i) ...{ return (i - 1) / 2; }
internal static Int32 LEFT(Int32 i) ...{ return 2 * i + 1; }
internal static Int32 RIGHT(Int32 i) ...{ return (2 * i + 2); }
#endregion
public Int32 Size ...{ get ...{ return m_Size; } }
public MaxHeap(Int32 size)
...{
m_Array = new Int32[size];
m_Size = Size;
BuildMaxHeap();
}
public MaxHeap(Int32[] inputArray)
...{
if (inputArray == null)
throw new ArgumentNullException("inputArray", "The input Array cannot be null!");
m_Array = inputArray;
m_Size = inputArray.Length;
BuildMaxHeap();
}
public String Show()
...{
// List the current heap elements
return Common.ListTheArray(m_Array);
}
6.2 Maintaining the heap property#region 6.2 Maintaining the heap property
private void MaxHeapify(Int32 root)
...{
if (root < 0 || root >= m_Array.Length)
throw new ArgumentOutOfRangeException("root", root, "input root node out of range");
Int32 heapSize = m_Size;
Int32 left, right, largest;
do
...{
largest = root;
left = LEFT(root);
right = RIGHT(root);
if (left < heapSize && m_Array[left] > m_Array[root])
largest = left;
if (right < heapSize && m_Array[right] > m_Array[largest])
largest = right;
if (largest != root)
...{
Common.Exchange(ref m_Array[root], ref m_Array[largest]);
root = largest;
continue;
}
else
break;
} while (root < m_Size);
}
#endregion
6.3 Building a max heap#region 6.3 Building a max heap
private void BuildMaxHeap()
...{
for (Int32 i = m_Size / 2 - 1; i >= 0; i--) MaxHeapify(i);
}
#endregion
Veriry a max heap#region Veriry a max heap
public bool IsMaxHeap(Int32 root)
...{
for (Int32 i = root; i < m_Size; i++)
...{
if (LEFT(i) < m_Size && m_Array[LEFT(i)] > m_Array[i]) return false;
if (RIGHT(i) < m_Size && m_Array[RIGHT(i)] > m_Array[i]) return false;
}
return true;
}
#endregion
6.4 The heapsort algorithm(Sort to non-increasing order)#region 6.4 The heapsort algorithm(Sort to non-increasing order)
/**//// <summary>
/// The heapsort algorithm(Sort to non-increasing order)
/// </summary>
public void Sort()
...{
BuildMaxHeap();
for (Int32 i = m_Array.Length - 1; i > 0; i--)
...{
Common.Exchange(ref m_Array[0], ref m_Array[i]);
m_Size--;
MaxHeapify(0);
}
m_Size = m_Array.Length;
}
#endregion
6.5 Priority queues#region 6.5 Priority queues
public Int32 Maximum()
...{
return m_Array[0];
}
public Int32 ExtractMax()
...{
if (m_Size < 1) throw new ApplicationException("heap underflow!");
Int32 max = m_Array[0];
m_Array[0] = m_Array[(m_Size--) - 1];
MaxHeapify(0);
return max;
}
public void IncreaseKey(Int32 Index, Int32 Key)
...{
if(m_Array[Index] > Key) throw new ArgumentException("new key is smaller than current key","Key, Index");
m_Array[Index] = Key;
while(Index > 0 && m_Array[PARENT (Index)] < m_Array[Index])
...{
Common.Exchange (ref m_Array[Index], ref m_Array[PARENT (Index)]);
Index = PARENT (Index);
}
}
/**//// <summary>
/// Inserts the element Key into the heap
/// </summary>
/// <param name="Key"></param>
public void Insert(Int32 Key)
...{
if( m_Size++ > m_Array.Length)
...{
Int32[] newLocationArray = new Int32[m_Array.Length * 2];
m_Array.CopyTo(newLocationArray, 0);
m_Array = newLocationArray;
}
m_Array[m_Size - 1] = Int32.MinValue;
IncreaseKey(m_Size - 1, Key);
}
// The operation HEAP-DELETE(A, i) deletes the item in node i from heap A.
public void Delete(Int32 Index)
...{
if (Index < 0 || Index >= m_Size)
throw new ArgumentOutOfRangeException("Index", Index, "Input wrong index!");
Common.Exchange(ref m_Array[Index], ref m_Array[m_Size - 1]);
m_Size--;
if (Index >= m_Size) return;
Int32 Key = m_Array[Index];
if (Key > m_Array[PARENT(Index)])
while (Index > 0 && Key > m_Array[PARENT(Index)])
...{
Common.Exchange(ref m_Array[Index], ref m_Array[PARENT(Index)]);
Index = PARENT(Index);
}
else
MaxHeapify(Index);
}
#endregion
}
}
}