Я только что реализовал алгоритм heapsort. Я стремлюсь к как можно меньшему количеству сравнений. Моя реализация работает, но делает в два раза больше сравнений, чем этот образец, который я нашел в Интернете: http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
Тестовый массив: 6 2 3 1 5 4 2 5 1 6 7 4 3 2 6 7 3 2 5 6 1 8 7 5 4 3 2 1 5
Образец, который я нашел в Интернете, сделал 194 сравнения для сортировки этого массива, моя реализация сделала 570 сравнений.
Вот код:
$(document).ready(function(){
init();
});
var comparisons = 0;
var init = function()
{
var dataSource = getTestData();
var root = {value: dataSource[0]};
//Building heap
for(var i = 1; i < dataSource.length; i++)
addChild(root, {value: dataSource[i]});
console.log("--- Source: ---")
console.log(JSON.stringify(dataSource));
console.log("--- Input: ---")
console.log(JSON.stringify(dataSource));
console.log("--- Tree: ---")
console.log(JSON.stringify(root, null, 4));
console.log("Nodes: " + countChildren(root));
var sortedArray = new Array();
comparisons = 0;
//Do sorting here
while(countChildren(root) != 0){
sortNode(root); //Sorting heap
sortedArray.unshift(root.value); //Adding the biggest entry from the top of the heap to the output
deleteNode(root); //Removing the top of the heap
}
console.log("--- Sorted Tree: ---")
console.log(JSON.stringify(root, null, 4));
console.log("Nodes: " + countChildren(root));
console.log("--- Sorted: ---")
console.log(JSON.stringify(sortedArray));
console.log("!!! Comparisons: " + comparisons + " !!!");
}
var deleteNode = function(item)
{
if (item.left == null && item.right == null)
item.value = null;
else if (item.left != null) {
item.value = item.left.value;
if (countChildren(item.left) == 1)
item.left = null;
else
deleteNode(item.left)
}
else if (item.right != null) {
item.value = item.right.value;
if (countChildren(item.right) == 1)
item.right = null;
else
deleteNode(item.right)
}
}
var sortNode = function(item)
{
if (item.left != null && item.right == null){
sortNode(item.left);
comparisons++;
if (item.value < item.left.value) //Comparison
{
var tmp = item.value;
item.value = item.left.value;
item.left.value = tmp;
}
}else if (item.right != null && item.left == null){
sortNode(item.right);
comparisons++;
if (item.value < item.right.value) //Comparison
{
var tmp = item.value;
item.value = item.right.value;
item.right.value = tmp;
}
}
else if (item.right != null && item.left != null) {
sortNode(item.right);
sortNode(item.left);
//Some more comparisons
var left_bigger_right = (item.right.value <= item.left.value); comparisons++;
var left_bigger_this = (item.value < item.left.value); comparisons++;
var right_bigger_this = (item.value < item.right.value); comparisons++;
if ((left_bigger_this && left_bigger_right) || (right_bigger_this && left_bigger_right)) {
var tmp = item.value;
item.value = item.left.value;
item.left.value = tmp;
}
else if (right_bigger_this && left_bigger_right == false){
var tmp = item.value;
item.value = item.right.value;
item.right.value = tmp;
}
}
else{ //No children
//Nothing to do :)
}
}
var addChild = function(item, toAdd)
{
if(item.left == null)
item.left = toAdd;
else if (item.right == null)
item.right = toAdd;
else{ //if(item.left != null && item.right != null)
childrenCountLeft = countChildren(item.left);
childrenCountRight = countChildren(item.right);
if (childrenCountRight < childrenCountLeft)
addChild(item.right, toAdd);
else if (childrenCountLeft < childrenCountRight)
addChild(item.left, toAdd);
else //if (childrenCountLeft == childrenCountRight)
addChild(item.left, toAdd);
}
}
var countChildren = function(item){
var children = 0;
if (item.value != null)
children += 1;
if (item.left != null)
children += countChildren(item.left);
if (item.right != null)
children += countChildren(item.right);
return children;
}
var getTestData = function(){
return new Array(6 ,2 ,3 ,1 ,5 ,4 ,2 ,5 ,1 ,6 ,7 ,4 ,3 ,2 ,6 ,7 ,3 ,2 ,5 ,6 ,1 ,8 ,7 ,5 ,4 ,3 ,2 ,1 ,5);
}
Мой вопрос: в какой части мне не удалось реализовать алгоритм пирамидальной сортировки? Где ненужные сравнения?
Они должны быть в функции sortNode. Все сравнения я отметил комментариями.
Я не вижу, как я могу улучшить эту функцию, чтобы делать меньше сравнений. Так что это будет мой вопрос.
sortNode
? Я еще не сталкивался с такой вещью в сортировке кучи, но, возможно, она просто неправильно названа. - person Bergi   schedule 30.03.2015