堆是一种排序较为高效的数据结构,一般而言,对规模为n的数据进行排序可以将时间复杂度优化到O(nlogk)。java中已经对堆有实现好的官方库:优先队列(PriorityQueue)。一般而言的堆有两种实现方式:数组和树节点实现,目前网上基于数组的实现方式较多,树节点相较而言需要考虑较多的越界和空指针情况,比较繁琐,这里提供一种较为完善的实现。
通过new关键字新建堆后,可以通过调用build方法输入一个Node节点的数组批量初始化,也可以不调用,通过不断调用insert方法单个插入值。
文章提供的是小根堆,相较而言,将其转换成大根堆也并不复杂。
class Tree{
public Node root;
public int count = 1;
public void build(Node[] build) {
int length = build.length;
root = build[0];
if(length > 1) {
for(int i = 1; i < length; i++) {
if(i%2 == 1) {
build[i].parent = build[(i-1)/2];
build[(i-1)/2].left = build[i];
}
else {
build[i].parent = build[(i-1)/2];
build[(i-1)/2].right = build[i];
}
Node save = build[i];
while(save.parent != null && save.data <= save.parent.data) {
int tempsave = save.data;
save.data = save.parent.data;
save.parent.data = tempsave;
save = save.parent;
}
}
}
count += length-1;
}
public void insert(int data) {
Node add = new Node(data);
if(root == null) {
root = add;
}
else {
count ++ ;
StringBuilder binary = new StringBuilder();
binary = Binary(count,binary);
String temp = binary.toString();
char[] order = temp.toCharArray();
int length = order.length;
Node current = root;
for(int k = 1; k < length-1; k++) {
if(order[k] == '0') {
current = current.left;
}
else if(order[k] == '1') {
current = current.right;
}
}
if(order[length-1] == '0') {
current.left = add;
add.parent = current;
}
else if(order[length-1] == '1') {
current.right = add;
add.parent = current;
}
Node save = add;
while(save.parent != null && save.data <= save.parent.data) {
int tempsave = save.data;
save.data = save.parent.data;
save.parent.data = tempsave;
save = save.parent;
}
}
}
public void delete() {
StringBuilder binary = new StringBuilder();
binary = Binary(count, binary);
String temp = binary.toString();
char[] order = temp.toCharArray();
int length = order.length;
Node current = root;
for(int k = 1; k < length; k++) {
if(order[k] == '0') {
current = current.left;
}
else if(order[k] == '1') {
current = current.right;
}
}
int thisdata = current.data;
if(length == 1) {
count -- ;
root = null;
return;
}
else if(length == 2) {
if(order[length-1] == '0') {
root.left = null;
}
else if(order[length-1] == '1') {
root.right = null;
}
}
else {
if(order[length-1] == '0') {
current = current.parent;
current.left = null;
}
else if(order[length-1] == '1') {
current = current.parent;
current.right = null;
}
}
Node templeft = root.left;
Node tempright = root.right;
root = new Node(thisdata);
root.left = templeft;
root.right = tempright;
if(templeft != null) {
templeft.parent = root;
}
if(tempright != null) {
tempright.parent = root;
}
Node find = root;
while(find.left != null && find.right != null) {
if(find.data <= find.left.data && find.data <= find.right.data) {
break;
}
else if(find.data > find.left.data && find.data <= find.right.data) {
int tempsave = find.data;
find.data = find.left.data;
find.left.data = tempsave;
find = find.left;
}
else if(find.data <= find.left.data) {
int tempsave = find.data;
find.data = find.right.data;
find.right.data = tempsave;
find = find.right;
}
else {
int tempsave = find.data;
if(find.left.data < find.right.data) {
find.data = find.left.data;
find.left.data = tempsave;
find = find.left;
}
else {
find.data = find.right.data;
find.right.data = tempsave;
find = find.right;
}
}
}
if(find.left != null) {
if(find.data > find.left.data) {
int tempsave = find.data;
find.data = find.left.data;
find.left.data = tempsave;
}
}
count --;
}
public void query() {
System.out.println(root.data);
}
public static StringBuilder Binary(int value, StringBuilder binary) {
if(value > 0) {
int n = value % 2;
value /= 2;
binary.insert(0, n);
Binary(value, binary);
}
return binary;
}
}
class Node{
public int data;
public Node left = null;
public Node right = null;
public Node parent = null;
public Node(int data) {
this.data = data;
}
}