1. 顺序存储二叉树
底层存储数据的时候使用数组存储,顺序二叉树性质:
1. 顺序二叉树通常只考虑完全二叉树;
2. 第n个元素的左子节点为 2*n +1 ;
3. 第n个元素的右子节点为:2*n +2;
4. 第n个元素的父节点为 (n-1)/2;
5. n 表示二叉树中的第几个元素(按0开始编号).
代码:
public class ArrBinaryTree {
public static void main(String[] args) {
int[] a = {1, 2,3,4,5,6,7};
ArrayBinaryTree arrayBinaryTree = new ArrayBinaryTree(a);
arrayBinaryTree.preOrder(0);
}
}
//
class ArrayBinaryTree {
private int[] arr;
public ArrayBinaryTree(int[] arr) {
this.arr = arr;
}
//完成顺序存储二叉树的前序遍历
//index 为数组的下标
public void preOrder(int index) {
//如果数组为空, 或者arr.length == 0
if (arr == null || arr.length == 0) {
System.out.printf("数组为空,不能遍历\n");
return;
}
//先显示自己
System.out.println(arr[index]);
//向左
if ((index*2+1) < arr.length) {
preOrder(2*index + 1);
}
//向右
if ((index*2+2) < arr.length) {
preOrder(2*index + 2);
}
}
}
2. 堆排序
堆排序使用完全二叉树的性质:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆; 每个结点的值都小于或者等于其左右孩子结点的值,称为小顶堆,这里没有要求结点的左右孩子结点的值的大小关系。 平均时间复杂度为:O(nlogn),不稳定排序
代码:
public class HeapSortDemo {
public static void main(String[] args) {
//要求将数组进行升序排列
int[] a = {4, 6, 8, 5, 9};
heapSort(a);
System.out.println(Arrays.toString(a));
}
//将数组调整成大顶堆
public static void heapSort(int a[]) {
int tmp = 0;
System.out.println("堆排序");
//变成大顶堆了
for (int i = a.length/2 - 1; i >= 0; i --) {
adjustHeap(a, i, a.length);
}
//将堆元素与末尾元素交换,最大元素沉到数组末端
//重新调整结构,使其满足堆定义,然后继续将最大顶沉到数组末端
for (int j = a.length-1; j > 0; j-- ) {
tmp = a[j];
a[j] = a[0];
a[0] = tmp;
adjustHeap(a, 0, j);
}
}
/**
* 完成将以i对应的非叶子结点的树调整成大顶堆
* @param a 待调整的数组
* @param i 表示非叶子结点在数组中的索引
* @param length 表示对多少个元素进行调整
*/
//大堆向上冒泡,大的值往上冒
public static void adjustHeap(int a[], int i, int length) {
int tmp = a[i]; //保存当前非叶子结点的值
/**
* 1. k = i * 2 + 1 是i结点的左子结点
*/
for (int k = i * 2 + 1; k < length; k = k*2 +1) {
if ( k+1 < length && a[k] < a[k+1]) { //左子结点的值小于右子结点的值
k++; //k 指向右子结点
}
if (a[k] > tmp) { //子结点大于父结点
a[i] = a[k]; //把较大的值赋给当前结点
i = k; // i指向k, 继续循环比较
} else {
break;
}
}
//一颗树
a[i] = tmp;
}
}