一、二叉树的顺序存储
1.存储方式:
使用数组保存二叉树结构,方式即将二叉树用层序遍历方式放入数组中。一般只适合表示完全二叉树,因为非完全二叉树会有空间的浪费。这种方式的主要用法就是堆的表示。
2.下标关系:
下标从0开始,已知双亲(parent)的下标,则:
左孩子(left)下标 = 2 * parent + 1;
右孩子(right)下标 = 2 * parent + 2;
已知孩子(不区分左右)(child)下标,则:
双亲(parent)下标 = (child - 1) / 2;
二、堆
1.概念:
1.1 堆逻辑上是一棵完全二叉树
1.2堆物理上是保存在数组中
1.3满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆
1.4 反之,则是小堆,或者小根堆,或者最小堆
三、建堆
import java.util.Arrays;
public class Heap{
public int[] elem;
public int usedsize;
public Heap(){
this.elem = new int[10];
}
//建大堆
public void buildHeapBig(int[] array){
for (int i = 0;i < array.length;i++){
this.elem[i] = array[i];
this.usedsize++;
}
for (int i = (this.usedsize - 1) / 2;i >= 0;i--){
adjustDownBig(i,this.usedsize);
}
}
//向下调整大根堆
public void adjustDownBig(int parent,int len){
int child = (parent * 2) + 1;
while (child < len){
if (child + 1 < len && this.elem[child] < this.elem[child + 1]){
child++;
}
if (this.elem[parent] < this.elem[child]){
int temp = this.elem[child];
this.elem[child] = this.elem[parent];
this.elem[parent] = temp;
parent = child;
child = (parent * 2) + 1;
}else{
break;
}
}
}
//建小堆
public void buildHeapSmall(int[] array){
for (int i = 0;i < array.length;i++){
this.elem[i] = array[i];
this.usedsize++;
}
for (int i = (this.usedsize - 1) / 2;i >= 0;i--){
adjustDownSmall(i,this.usedsize);
}
}
//向下调整小根堆
public void adjustDownSmall(int parent,int len){
int child = (parent * 2) + 1;
while (child < len){
if (child + 1 < len && this.elem[child] > this.elem[child + 1]){
child++;
}
if (this.elem[parent] > this.elem[child]){
int temp = this.elem[child];
this.elem[child] = this.elem[parent];
this.elem[parent] = temp;
parent = child;
child = (parent * 2) + 1;
}else {
break;
}
}
}
//判满
public boolean isFull(){
if (this.usedsize == this.elem.length){
return true;
}
return false;
}
//扩容
public void increase(){
this.elem = Arrays.copyOf(this.elem,this.usedsize * 2);
}
//入队列
public void push(int val){
if (isFull()){
increase();
}
this.elem[this.usedsize] = val;
this.usedsize++;
adjustUp(this.usedsize - 1);
}
//向上调整(大堆)
public void adjustUp(int child){
int parent = (child - 1) / 2;
while (child > 0){
if (this.elem[parent] < this.elem[child]){
int temp = this.elem[parent];
this.elem[parent] = this.elem[child];
this.elem[child] = temp;
child = parent;
parent = (child - 1) / 2;
}else {
break;
}
}
}
//判空
public boolean isEmpty(){
if (this.usedsize == 0){
return true;
}
return false;
}
//出队列
public void pop(){
if (isEmpty())return;
int temp = this.elem[0];
this.elem[0] = this.elem[this.usedsize - 1];
this.elem[this.usedsize - 1] = temp;
this.usedsize--;
adjustDownBig(0,this.usedsize);
}
}