这一章,前言讲了为什么要排序?
接着介绍本章主题,堆排序。
那么什么又是堆呢?
一种数据结构,当然有很多性质,这个我在前面数据结构说过了,然后有两种。
1.大根堆-----它是用来堆排序的。
2.小根堆-----它是用来做优先级队列的。
清楚了这两种用途,那么我们来看代码:
关于堆排序:
public class heap_sort {
public static void heapsort(int [] a){
for(int i=a.length/2;i>=0;i--)
perDown(a,i,a.length);
for(int i=a.length-1;i>0;i--){
swap(a,0,i);
perDown(a,0,i);
}
}
private static void perDown(int[] a,int i,int n){
int child;
int tmp;
for(tmp=a[i];leftChild(i)<n;i=child){
child=leftChild(i);
if(child!=n-1&&a[child]<a[child+1])
child++;
if(tmp<a[child])
a[i]=a[child];
else
break;
}
a[i]=tmp;
}
private static int leftChild(int i){
return 2*i+1;
}
private static void swap(int[] a,int b,int c){
int temp=a[b];
a[b]=a[c];
a[c]=temp;
}
}
1.在主函数中,第一个for完成建堆,第二for完成排序过程
2.perDown()函数则完成书上面保持堆的性质。
3.整个过程就如我以前介绍的那个数据结构,堆排序思想是完全一样的。
利用了堆这种数据结构,实现在是优先级队列。
根据堆分为最大堆,最小堆,所以优先级队列也可以分为最大优先级队列和最小优先级队列。
优先级队列的概念和用途书上已经写的很清楚了。直接写出操作代码:
public class priorityQueue {
// 返回具有最大关键字的元素
int HeapMaximum(int [] a)
{
return a[0];
}
// 去掉并返回具有最大关键字的元素
// 注意:这里每次MaxHeapify的是heapsize
int HeapExtractMax(int [] a, int [] heapsize)
{
if(heapsize.length < 1)
System.out.println("Heap Underflow");
int max = a[0];
a[0] = a[heapsize.length];
heapsize.length--;
perDown(a, 0, heapsize.length);
return max;
}
// 将元素a[i]的值增加到key
void HeapIncreaseKey(int [] a, int i, int key)
{
if(key < a[i])
System.out.println("New key is smaller than current key");
a[i] = key;
while(i > 1 &&a[i/2] < a[i])
{
int temp = a[i];
a[i] = a[i/2];
a[i/2] = temp;
i /= 2;
}
}
// 插入关键字为key的元素
void MaxHeapInsert(int []a, int key, int [] heapsize)
{
const int -INF=99999;
heapsize.length++;
a[heapsize.length] = -INF;
HeapIncreaseKey(a, heapsize.length, key);
}
}
所谓最大优先级队列,它支持以上4种操作。
insert()把一个元素插入队列
maximum()返回队列中最大的元素
extract-max()去掉并返回现在队列的元素
crease-key()将一个元素增大到k时的优先级队列操作。
所有以上的操作,都是基于堆,这种数据结构,因为实现队列,其实还有别的数据结构,比如说,基本的队列,只要添加优先级数据域。