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;
}
}