堆排序
堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
最大堆的添加元素和删除元素过程
java代码实现
import java.util.Random;
public class MaxHeap<E extends Comparable<E>> {
private Array<E> arr;
public MaxHeap() {
}
public MaxHeap(int capactiy) {
this.arr = new Array<>(capactiy);
}
public MaxHeap(E[] arr) {
this.arr = new Array<>(arr);
for (int i = parent(this.arr.getData_size() - 1); i >= 0; i--) {
siftDown(i);
}
}
public static void main(String[] args) {
int n = 100;
int capacity = n;
Random random = new Random();
Integer[] ts = new Integer[n];
for (int i = 0; i < n; i++) {
int a = random.nextInt(100);
ts[i] = a;
}
MaxHeap<Integer> maxHeap = new MaxHeap<>(ts);
Object[] ss = maxHeap.sort();
for (int i = 0; i < ss.length; i++) {
ts[i] = Integer.parseInt(ss[i].toString());
}
for (int i = 0; i < ts.length; i++) {
System.out.println(ts[i]);
}
//maxHeap.printStrust();
}
// public static void main(String[] args) {
//
// int n = 100;
//
// int capacity = 37;
// MaxHeap<Integer> maxHeap = new MaxHeap<>(capacity);
// Random random = new Random();
// for (int i = 0; i < n; i++) {
// int a = random.nextInt(100);
// maxHeap.add(a);
// // System.out.println("add : "+a);
// // maxHeap.printStrust();
// }
//
// int[] arr = new int[capacity];
// for (int i = 0; i < capacity; i++) {
// System.out.println("=======================================================");
// maxHeap.printStrust();
// arr[i] = maxHeap.extractMax();
// System.out.println("---------删除---" + arr[i] + "-----------------");
// maxHeap.printStrust();
// }
//
//
// for (int i = 1; i < capacity; i++)
// if (arr[i - 1] < arr[i])
// throw new IllegalArgumentException("Error");
//
// System.out.println("Test MaxHeap completed.");
//
// }
/**
* ***堆排序***
*/
public Object[] sort() {
Object[] arr = new Object[this.getSize()];
int size = this.getSize();
for (int i = 0; i < size; i++) {
arr[i] = this.extractMax();
}
return arr;
}
/**
* 获得堆中元素的个数
*
* @return
*/
public int getSize() {
return this.arr.getData_size();
}
/**
* 获得堆是否为空
*
* @return
*/
public boolean isEmpty() {
return this.arr.isEmpty();
}
/**
* 获得父节点的索引
*
* @param index
* @return
*/
private int parent(int index) {
if (index == 0) {
throw new IllegalArgumentException("Index=0 doesn't have parent ");
}
return (index - 1) / 2;
}
/**
* 获得左孩子的索引
*
* @param index
* @return
*/
private int leftChild(int index) {
return index * 2 + 1;
}
/**
* 获得右孩子的索引
*
* @param index
* @return
*/
private int rightChild(int index) {
return index * 2 + 2;
}
/**
* 在堆底添加元素
*
* @param e
*/
public void add(E e) {
this.arr.addLast(e);
shiftUp(this.getSize() - 1);
}
private void shiftUp(int index) {
while (index > 0 && this.arr.get(this.parent(index)).compareTo(this.arr.get(index)) < 0) {
this.arr.swap(this.parent(index), index);
index = this.parent(index);
}
}
/**
* 获得堆中的最大的元素
*
* @return
*/
public E findMax() {
if (this.arr.getData_size() == 0) {
throw new IllegalArgumentException("FindMax failed. the heap is empty");
}
return arr.get(0);
}
/**
* 取出堆中最大的元素
*/
public E extractMax() {
E max = this.findMax();
arr.swap(0, this.arr.getData_size() - 1);
arr.removeLast();
this.siftDown(0);
return max;
}
private void siftDown(int index) {
while (this.leftChild(index) < this.getSize()) {
int leftIndex = this.leftChild(index);
int rightIndex = leftIndex + 1;
if (rightIndex < this.getSize() && this.arr.get(rightIndex).compareTo(this.arr.get(leftIndex)) > 0) {
leftIndex = rightIndex;
}
if (this.arr.get(index).compareTo(this.arr.get(leftIndex)) >= 0) {
return;
}
this.arr.swap(index, leftIndex);
index = leftIndex;
}
}
public void printStrust() {
System.out.println();
System.out.println(this.arr.get(0));
int i = 1;
while (true) {
int len = power(i);
int left = power(i) - 1;
for (int j = 0; j < len; j++) {
if (j + left >= this.getSize()) {
System.out.println();
return;
}
System.out.print(this.arr.get(j + left) + "\t");
}
i++;
System.out.println();
}
}
private int power(int p) {
int ss = 1;
for (int i = 0; i < p; i++) {
ss *= 2;
}
return ss;
}
/**
* 底层的数组
*
* @param <E>
*/
private class Array<E> {
private E[] data;
private int data_size;
private int capacity;
public Array(E[] data) {
this.data = data;
this.data_size = data.length;
this.capacity = this.data_size;
}
public Array(int capacity) {
this.capacity = capacity;
this.data = (E[]) new Object[capacity];
this.data_size = 0;
}
/**
* 获得数组的长度
*
* @return
*/
public int getData_size() {
return this.data_size;
}
public boolean isEmpty() {
return this.data_size == 0;
}
/**
* 在数组尾部添加元素
*
* @param e
*/
public void addLast(E e) {
if (this.data_size == this.capacity) {
this.data_size--;
}
this.data[data_size] = e;
this.data_size++;
}
/**
* 获得 索引为index 的元素
*
* @param index
* @return
*/
public E get(int index) {
if (index < 0 || index > this.data_size) {
throw new IllegalArgumentException("Get failed. illegal index. ");
}
return this.data[index];
}
public E removeLast() {
this.data_size--;
return this.data[this.data_size];
}
public void swap(int i, int j) {
E ss = this.data[i];
this.data[i] = this.data[j];
this.data[j] = ss;
}
}
}
堆排序
/**
* 堆排序
*/
public Object[] sort() {
Object[] arr = new Object[this.getSize()];
int size = this.getSize();
for (int i = 0; i < size; i++) {
arr[i] = this.extractMax();
}
return arr;
}
测试结果
99
98
97
97
97
94
94
93
92
92
90
90
90
89
88
87
87
87
86
86
86
84
83
83
83
80
79
77
75
74
74
74
71
70
68
68
68
65
65
63
61
60
59
59
58
57
55
55
54
52
51
47
47
47
47
46
46
45
45
45
44
42
42
40
40
33
33
28
27
25
25
24
23
22
19
18
18
18
17
15
14
14
13
13
11
11
9
9
9
7
5
5
4
3
3
3
2
2
2
0