Skip to content

Commit 439c9cf

Browse files
authored
Merge pull request #86 from Gutsonok/master
Fixed #84 MaxHeap bad algorithm
2 parents 781ae31 + a9fe19a commit 439c9cf

File tree

3 files changed

+197
-42
lines changed

3 files changed

+197
-42
lines changed

DataStructures/Heaps/BinaryMaxHeap.cs

+21-12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ private void _buildMaxHeap()
4444
}
4545
}
4646

47+
/// <summary>
48+
/// Private Method. Used to restore heap condition after insertion
49+
/// </summary>
50+
private void _siftUp(int nodeIndex)
51+
{
52+
int parent = (nodeIndex - 1) / 2;
53+
while (_heapComparer.Compare(_collection[nodeIndex], _collection[parent]) > 0)
54+
{
55+
_collection.Swap(parent, nodeIndex);
56+
nodeIndex = parent;
57+
parent = (nodeIndex - 1) / 2;
58+
}
59+
}
60+
4761
/// <summary>
4862
/// Private Method. Used in Building a Max Heap.
4963
/// </summary>
@@ -110,11 +124,10 @@ public T this[int index]
110124

111125
_collection[index] = value;
112126

113-
if (_heapComparer.Compare(_collection[index], _collection[0]) >= 0) // greater than or equal to max
114-
{
115-
_collection.Swap(0, index);
116-
_buildMaxHeap();
117-
}
127+
if (index != 0 && _heapComparer.Compare(_collection[index], _collection[(index - 1) / 2]) > 0) // greater than or equal to max
128+
_siftUp(index);
129+
else
130+
_maxHeapify(index, _collection.Count - 1);
118131
}
119132
}
120133

@@ -144,14 +157,10 @@ public void Initialize(IList<T> newCollection)
144157
/// </summary>
145158
public void Add(T heapKey)
146159
{
147-
if (IsEmpty)
160+
_collection.Add(heapKey);
161+
if (!IsEmpty)
148162
{
149-
_collection.Add(heapKey);
150-
}
151-
else
152-
{
153-
_collection.Add(heapKey);
154-
_buildMaxHeap();
163+
_siftUp(_collection.Count - 1);
155164
}
156165
}
157166

DataStructures/Heaps/BinaryMinHeap.cs

+21-12
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,20 @@ private void _buildMinHeap()
4545
}
4646
}
4747

48+
/// <summary>
49+
/// Private Method. Used to restore heap condition after insertion
50+
/// </summary>
51+
private void _siftUp(int nodeIndex)
52+
{
53+
int parent = (nodeIndex - 1) / 2;
54+
while (_heapComparer.Compare(_collection[nodeIndex], _collection[parent]) < 0)
55+
{
56+
_collection.Swap(parent, nodeIndex);
57+
nodeIndex = parent;
58+
parent = (nodeIndex - 1) / 2;
59+
}
60+
}
61+
4862
/// <summary>
4963
/// Private Method. Used in Building a Min Heap.
5064
/// </summary>
@@ -115,11 +129,10 @@ public T this[int index]
115129

116130
_collection[index] = value;
117131

118-
if (_heapComparer.Compare(_collection[index], _collection[0]) <= 0) // less than or equal to min
119-
{
120-
_collection.Swap(0, index);
121-
_buildMinHeap();
122-
}
132+
if (index != 0 && _heapComparer.Compare(_collection[index], _collection[(index - 1) / 2]) < 0) // less than or equal to min
133+
_siftUp(index);
134+
else
135+
_minHeapify(index, _collection.Count - 1);
123136
}
124137
}
125138

@@ -151,14 +164,10 @@ public void Initialize(IList<T> newCollection)
151164
/// <param name="heapKey">Heap key.</param>
152165
public void Add(T heapKey)
153166
{
154-
if (IsEmpty)
167+
_collection.Add(heapKey);
168+
if (!IsEmpty)
155169
{
156-
_collection.Add(heapKey);
157-
}
158-
else
159-
{
160-
_collection.Add(heapKey);
161-
_buildMinHeap();
170+
_siftUp(_collection.Count - 1);
162171
}
163172
}
164173

UnitTest/DataStructuresTests/BinaryHeapsTest.cs

+155-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using Algorithms.Sorting;
2-
using DataStructures.Heaps;
1+
using DataStructures.Heaps;
2+
using System;
33
using System.Collections.Generic;
44
using Xunit;
55

@@ -8,7 +8,7 @@ namespace UnitTest.DataStructuresTests
88
public static class MinHeapTest
99
{
1010
[Fact]
11-
public static void DoTest()
11+
public static void CheckOrderInHeap_RandomOrder_ReturnsTrue()
1212
{
1313
BinaryMinHeap<long> minHeap = new BinaryMinHeap<long>(Comparer<long>.Default);
1414

@@ -17,26 +17,163 @@ public static void DoTest()
1717
minHeap.Add(4);
1818
minHeap.Add(16);
1919
minHeap.Add(8);
20-
minHeap.Add(15);
20+
minHeap.Add(1);
21+
minHeap.Add(3);
22+
minHeap.Add(100);
23+
minHeap.Add(5);
24+
minHeap.Add(7);
25+
26+
var isRightOrder = IsRightOrderInHeap<long>(minHeap);
27+
Assert.True(isRightOrder);
28+
}
29+
30+
[Fact]
31+
public static void CheckOrderInHeap_AscendingOrder_ReturnsTrue()
32+
{
33+
BinaryMinHeap<long> minHeap = new BinaryMinHeap<long>(Comparer<long>.Default);
34+
35+
minHeap.Add(1);
36+
minHeap.Add(2);
37+
minHeap.Add(3);
38+
minHeap.Add(4);
39+
minHeap.Add(5);
40+
minHeap.Add(6);
41+
minHeap.Add(7);
42+
minHeap.Add(8);
43+
minHeap.Add(9);
44+
minHeap.Add(10);
45+
46+
var isRightOrder = IsRightOrderInHeap<long>(minHeap);
47+
Assert.True(isRightOrder);
48+
}
49+
50+
[Fact]
51+
public static void CheckOrderInHeap_DecreasingOrder_ReturnsTrue()
52+
{
53+
BinaryMinHeap<long> minHeap = new BinaryMinHeap<long>(Comparer<long>.Default);
54+
55+
minHeap.Add(10);
2156
minHeap.Add(9);
22-
minHeap.Add(55);
23-
minHeap.Add(0);
24-
minHeap.Add(34);
25-
minHeap.Add(12);
57+
minHeap.Add(8);
58+
minHeap.Add(7);
59+
minHeap.Add(6);
60+
minHeap.Add(5);
61+
minHeap.Add(4);
62+
minHeap.Add(3);
2663
minHeap.Add(2);
27-
minHeap.Add(93);
28-
minHeap.Add(14);
29-
minHeap.Add(27);
64+
minHeap.Add(1);
65+
66+
var isRightOrder = IsRightOrderInHeap<long>(minHeap);
67+
Assert.True(isRightOrder);
68+
}
69+
70+
public static bool IsRightOrderInHeap<T>(BinaryMinHeap<T> binaryMinHeap) where T : IComparable<T>
71+
{
72+
var array = binaryMinHeap.ToArray();
73+
74+
for(int i=0; i * 2 + 1 < array.Length; ++i)
75+
{
76+
int leftChildIndex = i * 2 + 1;
77+
int rightChildIndex = leftChildIndex + 1;
78+
79+
if (array[i].CompareTo(array[leftChildIndex]) > 0)
80+
{
81+
return false;
82+
}
83+
84+
if (rightChildIndex < array.Length && array[i].CompareTo(array[rightChildIndex]) > 0)
85+
{
86+
return true;
87+
}
88+
}
89+
90+
return true;
91+
}
92+
}
93+
94+
public static class MaxHeapTest
95+
{
96+
[Fact]
97+
public static void CheckOrderInHeap_RandomOrder_ReturnsTrue()
98+
{
99+
BinaryMaxHeap<long> maxHeap = new BinaryMaxHeap<long>(Comparer<long>.Default);
100+
101+
maxHeap.Add(23);
102+
maxHeap.Add(42);
103+
maxHeap.Add(4);
104+
maxHeap.Add(16);
105+
maxHeap.Add(8);
106+
maxHeap.Add(1);
107+
maxHeap.Add(3);
108+
maxHeap.Add(100);
109+
maxHeap.Add(5);
110+
maxHeap.Add(7);
111+
112+
var isRightOrder = IsRightOrderInHeap<long>(maxHeap);
113+
Assert.True(isRightOrder);
114+
}
115+
116+
[Fact]
117+
public static void CheckOrderInHeap_AscendingOrder_ReturnsTrue()
118+
{
119+
BinaryMaxHeap<long> maxHeap = new BinaryMaxHeap<long>(Comparer<long>.Default);
120+
121+
maxHeap.Add(1);
122+
maxHeap.Add(2);
123+
maxHeap.Add(3);
124+
maxHeap.Add(4);
125+
maxHeap.Add(5);
126+
maxHeap.Add(6);
127+
maxHeap.Add(7);
128+
maxHeap.Add(8);
129+
maxHeap.Add(9);
130+
maxHeap.Add(10);
131+
132+
var isRightOrder = IsRightOrderInHeap<long>(maxHeap);
133+
Assert.True(isRightOrder);
134+
}
135+
136+
[Fact]
137+
public static void CheckOrderInHeap_DecreasingOrder_ReturnsTrue()
138+
{
139+
BinaryMaxHeap<long> maxHeap = new BinaryMaxHeap<long>(Comparer<long>.Default);
140+
141+
maxHeap.Add(10);
142+
maxHeap.Add(9);
143+
maxHeap.Add(8);
144+
maxHeap.Add(7);
145+
maxHeap.Add(6);
146+
maxHeap.Add(5);
147+
maxHeap.Add(4);
148+
maxHeap.Add(3);
149+
maxHeap.Add(2);
150+
maxHeap.Add(1);
151+
152+
var isRightOrder = IsRightOrderInHeap<long>(maxHeap);
153+
Assert.True(isRightOrder);
154+
}
155+
156+
public static bool IsRightOrderInHeap<T>(BinaryMaxHeap<T> binaryMaxHeap) where T : IComparable<T>
157+
{
158+
var array = binaryMaxHeap.ToArray();
159+
160+
for (int i = 0; i * 2 + 1 < array.Length; ++i)
161+
{
162+
int leftChildIndex = i * 2 + 1;
163+
int rightChildIndex = leftChildIndex + 1;
30164

31-
var array = minHeap.ToArray();
32-
Assert.True(array.Length == minHeap.Count, "Wrong size.");
165+
if (array[i].CompareTo(array[leftChildIndex]) < 0)
166+
{
167+
return false;
168+
}
33169

34-
var list = minHeap.ToList();
35-
Assert.True(list.Count == minHeap.Count, "Wrong size.");
170+
if (rightChildIndex < array.Length && array[i].CompareTo(array[rightChildIndex]) > 0)
171+
{
172+
return true;
173+
}
174+
}
36175

37-
array.HeapSortDescending();
38-
var maxHeap = minHeap.ToMaxHeap();
39-
Assert.True(maxHeap.Peek() == array[0], "Wrong maximum.");
176+
return true;
40177
}
41178
}
42179
}

0 commit comments

Comments
 (0)