HeapSort function not sorting correctly

I have a Max Heap implemented using a vector. The trickeUpRec() and trickleDownRec() functions move the vector nodes into their correct positions in order to satisfy the rules for a Max Heap.

I also have a HeapSort() function which should sort a vector of 1000 ints although it gives the incorrect output. Can anyone see why?

I have also templated the class in order to use chars etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
using namespace std;


template <typename T>
class Heap
{
private:

	vector<T> vec;

	// return parent of vec[i] if i is not already a root node
	int PARENT(int i)
	{
		return (i - 1) / 2;
	}

	// return left child of vec[i]	
	int LEFT(int i)
	{
		return (2 * i + 1);
	}

	// return right child of vec[i]	
	int RIGHT(int i)
	{
		return (2 * i + 2);
	}



	void trickleDownRec(int i)
	{

		// get left and right child of node at index i
		int left = LEFT(i);
		int right = RIGHT(i);

		int largest = i;

		// compare vec[i] with its left and right child
		// and find largest value
		if (left < vec.size() && vec[left] > vec[i])
			largest = left;

		if (right < vec.size() && vec[right] > vec[largest])
			largest = right;

		// swap with child having greater value and 
		// call heapify-down on the child
		if (largest != i) {
			swap(vec[i], vec[largest]);
			trickleDownRec(largest);
		}
	}


	void trickleUpRec(int i)
	{
		// check if node at index i and its parent violates 
		// the heap property
		if (i && vec[PARENT(i)] < vec[i])
		{
			// swap the two if heap property is violated
			swap(vec[i], vec[PARENT(i)]);

			// call Heapify-up on the parent
			trickleUpRec(PARENT(i));
		}
	}


public:


	void heapSort()
	{
		int n = vec.size();

		// One by one extract an element from heap 
		for (int i = n - 1; i >= 0; i--) {
			// Move current root to end 
			swap(vec[0], vec[i]);

			// call max heapify on the reduced heap 
			trickleDownRec(i);
		}
	}


	void display()
	{
		for (int i = 0; i < vec.size(); i++)
		{
			cout << vec.at(i) << ", ";
		}
	}


	// insert key into the heap
	void insert(int key)
	{
		// insert the new element to the end of the vector
		vec.push_back(key);

		// get element index and call heapify-up procedure
		int index = vec.size() - 1;
		trickleUpRec(index);
	}

	// function to remove element with highest priority (present at root)
	void remove()
	{
		try {
			// if heap has no elements, throw an exception
			if (vec.size() == 0)
				throw out_of_range("Vector<X>::at() : "
					"index is out of range(Heap underflow)");

			// replace the root of the heap with the last element
			// of the vector
			vec[0] = vec.back();
			vec.pop_back();

			// call heapify-down on root node
			trickleDownRec(0);
		}
		// catch and print the exception
		catch (const out_of_range & oor) {
			cout << "\n" << oor.what();
		}
	}
};


int main()
{
	Heap<int> pq;

	pq.insert(3);
	pq.insert(2);
	pq.insert(15);

	pq.insert(5);
	pq.insert(4);
	pq.insert(45);

	cout << "Max Heap: \n";
	pq.display();

	pq.remove();
	cout << "\n";
	pq.display();

	

	Heap<int> pq2;
	for (int i = 0; i < 1000; i++)
	{
		int j = rand() % 1000;
		pq2.insert(j);
	}

	cout << "\nHeap Sort for Vector of 1000 random ints: \n";
	pq2.heapSort();
	pq2.display();



	return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
	void heapSort()
	{
		int n = vec.size();

		// One by one extract an element from heap 
		for (int i = n - 1; i >= 0; i--) {
			// Move current root to end 
			swap(vec[0], vec[i]);

			// call max heapify on the reduced heap
			trickleDownRec(i);
		}
	}

pen and paper and simulate that function.
you say «call max heapify on the reduced heap» but at no point you reduce the heap
the first time you call `trickleDownRec(n-1)', that would do nothing

tricleDown should start at 0, but not going beyond i
I have tried to fix it, although can not get a solution without changing the parameters around. Can anyone help me out with some code please?
Last edited on
got it fixed with the following

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

void trickleDownRec(int n, int i)
	{

		// get left and right child of node at index i
		int left = LEFT(i);
		int right = RIGHT(i);

		int largest = i;

		// compare vec[i] with its left and right child
		// and find largest value
		if (left < n && vec[left] > vec[i])
			largest = left;

		if (right < n && vec[right] > vec[largest])
			largest = right;

		// swap with child having greater value and 
		// call heapify-down on the child
		if (largest != i) {
			swap(vec[i], vec[largest]);
			trickleDownRec(n, largest);
		}
	}


void heapSort()
	{
		int n = vec.size();
		for (int i = n - 1; i >= 0; i--) {
			swap(vec[0], vec[i]);
			trickleDownRec(i, 0);
		}
	}
Topic archived. No new replies allowed.