堆排序:
1,开始建堆,已一个小根堆为例:(图片摘自别人,与下面的排序代码无关)
构造好了堆之后,下面就是排序的过程:
直接上代码了:
public class HeapSort {
public void sift(int[] arr, int index, int length){
int temp = arr[index];//先取出当前元素i
for(int k=index*2+1; k<length; k=k*2+1){//从i结点的左子结点开始,也就是2i+1处开始
if(k+1<length && arr[k]<arr[k+1]){//如果左子结点小于右子结点,k指向右子结点
k++;
}
if(arr[k] >temp){//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
arr[index] = arr[k];
index = k;
}else{
break;
}
}
arr[index] = temp;//将temp值放到最终的位置
}
public void sort(int[] arr){
for(int i=arr.length/2-1;i>=0;i--){
//从第一个非叶子结点从下至上,从右至左调整结构
sift(arr,i,arr.length);
}
//2.调整堆结构+交换堆顶元素与末尾元素
for(int j=arr.length-1;j>0;j--){
swap(arr,0,j);//将堆顶元素与末尾元素进行交换
sift(arr,0,j);//重新对堆进行调整
}
}
public void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {1,43,6,4,3,2,5};
new HeapSort().sort(arr);
System.out.println(Arrays.toString(arr));
}
}
由于是从第二个元素开始排序的也就是a[1],所以第一个元素没有排序,可以在初始化的时候声明为0。
2017/8/7/13:32
今天在算法导论上看到一种用递归实现的方法,只需要把上面的sift方法换一下即可:
void sift2(int a[],int m,int n)
{
int i = m,j = 2*m,k=2*m+1;
int largest;
if(largest > n)return;
if(a[i]>a[j])largest = i;
else j = largest;
if(a[k]>a[largest]) largest = k;
if(i!= largest)
{
swaps(&a[i],&a[largest]);
sift2(a,largest,n);
}
}
2020.12.2,时隔三年,再对堆进行一遍温习,以大根堆为例:
手写最大堆代码如下:
import java.util.Arrays;
public class MaxHeap {
private int[] data;
private int size;
private int capacity;
public MaxHeap(int msize){
this.size = 0;
this.capacity = msize;
data = new int[msize+1];
}
public void insert(int v){
if(size == capacity) {
System.out.println("heap is full");
return;
}
data[++size] = v;
shiftup(size);
}
private void shiftup(int index) {
while(index > 1 && data[index] > data[index/2]){
int t = data[index];
data[index] = data[index/2];
data[index/2] = t;
index /= 2;
}
}
public int deleteMax(){
if(size == 0) {
System.out.println("堆已经是空的");
return -1;
}
int res = data[1];
data[1] = data[size--];
shiftdown(1);
return res;
}
private void shiftdown(int i) {
while(2 * i <= size){
int j = (i << 1);
if(j + 1 <= size && data[j] < data[j+1]) j++;
if(data[i] > data[j]) break;
int t = data[i];
data[i] = data[j];
data[j] = t;
i = j;
}
}
public static void main(String[] args) {
int[] arr = {3,7,10,45,13,3};
MaxHeap heap = new MaxHeap(arr.length);
for(int v: arr) {
heap.insert(v);
}
for(int i = arr.length-1; i >= 0; i--){
arr[i] = heap.deleteMax();
}
System.out.println(Arrays.toString(arr));
}
}