目前我有一个家庭工作问题,
可以通过以下方式提高堆排序算法的效率 编写一个方法,一次命令整个列表而不是 一次添加一个元素。
但是我无法弄清楚它是什么意思“而不是一次添加一个元素”,当然必须首先构建一个堆(这涉及逐个添加未排序列表中的元素),然后删除一次一个堆中最大的。
这是我的堆数组:
import exceptions.exceptions.*;
public class ArrayHeap<T> extends ArrayBinaryTree<T> implements HeapADT<T> {
public ArrayHeap(){
super();
}
public void addElement (T element){
if (count==size())
expandCapacity();
tree[count] = element;
count++;
if (count > 1)
heapifyAdd();
}
private void heapifyAdd(){
int index = count - 1;
while ((index != 0) && (((Comparable)tree[index]).compareTo(tree[(index-1)/2]) < 0))
{
T temp = tree[index];
tree[index] = tree[(index-1)/2];
tree[(index-1)/2] = temp;
index = (index-1)/2;
}
}
public T removeMin(){
if (isEmpty())
throw new EmptyCollectionException ("Empty Heap");
T minElement = findMin();
tree[0] = tree[count-1];
heapifyRemove();
count--;
return minElement;
}
private void heapifyRemove()
{
T temp;
int node = 0;
int left = 1;
int right = 2;
int next;
if ((tree[left] == null) && (tree[right] == null))
next = count;
else if (tree[left] == null)
next = right;
else if (tree[right] == null)
next = left;
else if (((Comparable)tree[left]).compareTo(tree[right]) < 0)
next = left;
else
next = right;
while ((next < count) && (((Comparable)tree[next]).compareTo(tree[node]) < 0)){
temp = tree[node];
tree[node] = tree[next];
tree[next] = temp;
node = next;
left = 2*node + 1;
right = 2*(node+1);
if ((tree[left] == null) && (tree[right] == null))
next = count;
else if (tree[left] == null)
next = right;
else if (tree[right] == null)
next = left;
else if (((Comparable)tree[left]).compareTo(tree[right]) < 0)
next = left;
else
next = right;
}
}
public T findMin() {
if (isEmpty())
throw new EmptyCollectionException ("Empty Heap");
return tree[0];
}
}
以下是更多HeapSort算法:
import ArrayHeap;
public class HeapSort<T>{
public T[] heapsort(T[] data, int min, int max){
ArrayHeap<T> temp = new ArrayHeap<T>();
for (int c = min; c <= max; c++){
temp.addElement(data[c]);
}
int count = min;
while(!(temp.isEmpty())){
T jj = temp.removeMin();
data[count] = jj;
count ++;
}
return data;
}
答案 0 :(得分:2)
执行heapsort最直接的方法是使用单独的堆并将所有元素添加到它中,然后当我们逐个弹出它们时,元素将按顺序排列。这就是&#34;一次添加一个元素&#34;在语句中引用,这就是你的实现正在做的事情:创建一个类型ArrayHeap
的堆并向其插入data
的元素,最后将元素弹回到{{1} }。
一种更有效的方式(在空间和时间方面)是执行就地排序,我们使用数组作为堆进行排序,而不是使用额外的内存堆,这就是&#34;一次订购整个清单&#34;是指。这个实现的步骤如下,我们将按非递减顺序对元素进行排序:
data
= n - 1到1:
i
元素交换数组中的0
个元素。i
)。i
操作以恢复最大堆属性。请注意,只要max-heap属性成立,堆中最顶层的元素就是最大的元素,所以在sift-down
- 迭代的开始(k
这里){ {1}} - 元素是k = n - i
- 最大元素,我们通过交换放置在数组中的正确位置。
请注意,步骤1可以在0
中完成,在步骤2中有k
次迭代,每次O(n)
操作需要时间O(n)
,因此整体时间复杂度是sift-down
。
以下是Java实现,供您参考:
O(log(n))