在本例中实现了堆数据结构,sort()方法排序堆实例。
import java.util.Comparator; import java.util.Iterator; import java.util.function.Consumer; /** * 二叉堆 * 成员变量:数组 arr、元素数量 count、 * 成员方法:是否空 isEmpty 、大小 size、插入 insert、删除最大值并返回 deleteMax、 * 比较less、交换exch、下沉sink、上浮swim */ public class Heap <Key extends Comparable<Key>> implements Iterable<Key>{ private Key[] arr; //堆内部维护的数组 private int count; //数组内部的元素 public Heap(Key[] array){ count = array.length; arr = (Key[])new Comparable[count+1]; for(int i=1;i<=array.length;i++){ arr[i] = array[i-1]; } } public void resize(int size){ Key[] temp = (Key[])new Comparator[size]; for(int i=1;i<=count;i++){ temp[i]=arr[i]; } arr = temp; } public boolean isEmpty() { if(count==0)return true; return false; } public int size(){ return count; } public void insert(Key key){ if(count+1>=arr.length){ resize(count*2); } arr[count+1] = key; count++; swim(count); } public Key deleteMax(){ if(isEmpty()) return null; Key temp = arr[1]; exch(1,count); arr[count--]=null; sink(1,count); return temp; } public boolean less(int a,int b){ if(arr[a].compareTo(arr[b])<0) return true; return false; } public void exch(int a,int b){ Key temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } // sink() swim() 方法是堆数组的关键 public void sink(int k, int n){ while (2*k<=n){//有子节点 int j=2*k; if(j+1<=n && less(j,j+1)) j++; if(less(j,k)) break; exch(j,k); k=j; } } public void swim(int k){ int j=k/2; while (j>=1){//有父节点 if(less(j,k)){ exch(j,k); k=j; } } } public void sort(){ //初始化数组 //从倒数的二排开始使用sink()方法逐渐是整个堆有序化 for(int i = count/2; i>=1; i--){ sink(i,count); } System.out.println("初始化结束"); //排序 int N = count; while(N>1){ exch(1,N--); sink(1,N); //注意! 此处sink()方法的第二个参数为N; 因为需要sink()方法排序堆的大小为N } System.out.println("排序结束"); } //迭代器 @Override public Iterator<Key> iterator() { return new Iterator<Key>() { int i = 1; @Override public boolean hasNext() { if(i<=count)return true; return false; } @Override public Key next() { return arr[i++]; } }; } }
/** * 测试案例 */ public class TestCase { public static void main(String[] args) { Integer[] a = new Integer[]{1,6,34,2,5,3,4,45,6,22}; Heap<Integer> integerHeap = new Heap<>(a); System.out.println("start sort"); integerHeap.sort(); System.out.println("sorted"); for(Integer e : integerHeap){ System.out.println(e); } } } //结果 start sort 初始化结束 排序结束 sorted 1 2 3 4 5 6 6 22 34 45
只使用堆排序,静态方法
public class HeapSort{ public static void sink(Comparable[] arr, int k, int n){ //使用了多态,要求数组实现Comparable接口 while (2*k<=n){//有子节点 int j=2*k; if(j+1<=n && less(arr,j,j+1)) j++; if(less(arr,j,k)) break; exch(arr,j,k); k=j; //k表示父节点、j表示较大的子节点。 } } public static boolean less(Comparable[] arr,int a,int b){ if(arr[a].compareTo(arr[b])<0) return true; return false; } public static void exch(Comparable[] arr, int a,int b){ Comparable temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } public static void sort(Comparable[] arr){ for(int i=arr.length/2;i>=1;i--){ sink(arr, i, arr.length-1); } int n=arr.length-1; while(n>1){ exch(arr,1,n--); sink(arr,1,n); } } }
import java.util.Arrays; /** * 测试案例 */ public class TestCase { public static void main(String[] args) { Integer[] arr = new Integer[]{0,1,6,34,2,5,3,4,45,6,22};//数组索引为0的位置不放元素 HeapSort.sort(arr); System.out.println(Arrays.toString(arr)); } } //结果 [0, 1, 2, 3, 4, 5, 6, 6, 22, 34, 45]