二叉树
满二叉树定义 ,这个可以认为是特殊的 完全二叉树
除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树。
国内教程定义:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。
大意为:如果一棵二叉树的结点要么是叶子结点,要么它有两个子结点,这样的树就是满二叉树。(一棵满二叉树的每一个结点要么是叶子结点,要么它有两个子结点,但是反过来不成立,因为完全二叉树也满足这个要求,但不是满二叉树)
完全二叉树定义, 相比 满二叉树定义 稍微 松一点
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
算法思路
判断一棵树是否是完全二叉树的思路
1>如果树为空,则直接返回错
2>如果树不为空:层序遍历二叉树
2.1>如果一个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列;
2.1>如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
2.2>如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子节点;该树才是完全二叉树,否则就不是完全二叉树
完全二叉树的 应用举例 最大堆 ,最小堆 ==》 堆排序 , 好了 看来我不适合写算法,脑仁疼。。。
package com.ghc.starter.algorithm;
/*
这是一个排序算法集合的工具类
* */
public class SortUtils {
public static int [] array = {10,9,3,2,4,6,5,7,8};
// 完全二叉树 --》最大堆--》堆排序
public static void main(String [] args){
printArray(array);
buildMaxHeap(array,array.length);
printArray(array);
heapSort(array);
printArray(array);
}
// 有格式的打印数组
public static void printArray(int [] array){
System.out.print("[");
for(int i=0;i<array.length;i++){
if(i!=array.length-1)
System.out.print(array[i]+",");
else System.out.println(array[i]+"]");
}
}
// 堆排序 基于 下面 构建 最大堆
public static void heapSort(int [] array){
// 如果 数组只有一个元素或者为空则不用排序
if(array==null || array.length<=1) return;
// 否则开始 堆排序
// 先 构建一个 最大堆
buildMaxHeap(array,array.length);
for(int i=array.length-1;i>0;i--){
// 交换 堆顶与 最后位置的值,下一次 跳过 已经排好序的 位置
swap(array,0,i);
// 递归 重复构建 跳过 排好序的位置后的 最大堆
buildMaxHeap(array,i);
}
}
// 根据传入的 数组 构建一个 最大堆 ,最大堆只能保证堆顶是最大值,那么堆排序就是每次取最值后然后调整堆为最大堆
public static void buildMaxHeap(int [] array,int heapSize){
// 从 总节点数的 1/2 之一处开始 逆序 调整 最大堆
for(int i=heapSize/2;i>0;i--){
maxHeapify(array,heapSize,i);
}
}
public static void maxHeapify(int [] array,int heapSize,int rootIndex){
//左叶子结点
int l = 2*rootIndex;
// 右叶子结点
int r = l+1;
// 调整需要的最大值指向
int largest = rootIndex;
//如果 左叶子结点比父节点要大 ,那么修改 largest 指向为 l
if(l<=heapSize && array[l-1]>array[rootIndex-1]){
largest = l;
}
//如果 右叶子结点比父节点要大 ,那么修改 largest 指向为 r
if(r<=heapSize && array[r-1]>array[largest-1]){
largest = r;
}
// 如果 最大值不是 父节点,那么交换 最大值指向与父节点的位置
if(largest!=rootIndex){
swap(array,largest-1,rootIndex-1);
if(largest<=heapSize/2){
maxHeapify(array,heapSize,largest);
}
}
}
// 交换 数组中的值
public static void swap(int [] array,int i,int j){
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
二叉搜索树
AVL 平衡树
红黑树
如果有来生,一个人去远行,看不同的风景,感受生命的活力。。。