二叉树:每个结点至多有两个子树
满二叉树:每一层的结点个数都是最大结点数
完全二叉树:叶子节点在最后两层;对于任一结点,左子树的深度比右子树深度大1或者相等
性质:
二叉树:第i层,至多有2^(i-1)个结点
二叉树:深度为k的二叉树,至多有(2^k)-1个结点
满二叉树:深度为k的满二叉树的结点个数为(2^k)-1
二叉树:任何一个二叉树,度为0的结点的个数n0,度为1的结点的个数n1,度为2的结点的个数的关系: n0 = n2+1,总的结点个数n
原因:n0+n1+n2 = n 除了根节点之外,其它几点都有一个分支进入分支个数n-1,分支都是由度为1或者度为2的结点发出的 n1+2*n2 = n-1 根据这两个公式得到n0=n2+1
完全二叉树:任何一个具有n个结点的完全二叉树的深度为 log以2为底n向下取整 + 1
完全二叉树:任何一个完全二叉树按照层次为结点编号
i=1,该结点是完全二叉树的根,无双亲
i>1,该节点不是根,该结点的双亲的编号为i/2向下取整
一个结点的编号是i,如果2*i大于n,表明该结点没有左孩子,否则,左孩子编号为2*i
一个结点的编号是i,如果2*i+1大于n,表明该结点没有右孩子,否则,右孩子编号为2*i
存储
(1)顺序存储
用一组地址连续的存储单元将二叉树从上到下从左到右按顺序存储,存储成对应的完全二叉树的形式(完全二叉树中编号为i的结点存储在数组下标为i-1的分量中),如果某个结点不存在,该位置存0
数组的长度(2^k)-1 二叉树的深度为k,空间浪费
(2)链式存储
数据域 左孩子 右孩子
指针域有浪费:含有n个结点的二叉树有n+1个空指针域 有n个结点,就有2*n个指针域,就有n-1个分支,所以,有n+1个指针浪费
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
@Override
public String toString() {
return "TreeNode [val=" + val + ", left=" + left + ", right=" + right
+ "]";
}
}
二叉树遍历
前序
public static void preOrder(TreeNode node){
//前序遍历,根左右,递归实现
//每次调用时,参数node都是当前子树的根节点
if(node == null){
//如果当前节点是null,直接返回
return;
}else{
//如果当前节点不是null,输出当前节点的值,然后遍历当前节点的左右子树
System.out.print(node.val+" ");
preOrder(node.left);
preOrder(node.right);
}
}
public static void preOrder2(TreeNode root){
//前序遍历,根左右,借助栈,非递归实现
//如果根节点是null,表明这是一棵空树,直接返回
if(root == null){
return;
}else{
//如果根节点不是null,遍历
Stack<TreeNode> stack = new Stack<TreeNode>();
//先将根节点入栈
stack.push(root);
while(!stack.isEmpty()){//栈空时,表明已经遍历完成
//弹出栈顶保存的那个节点,遍历其左右子树
TreeNode node = stack.pop();
System.out.print(node.val+" ");
//由于栈是先进后出的数据结构,因此,先将当前节点的右子树的根节点入栈,再将当前节点的左子树的根节点入栈
if(node.right != null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
}
}
}
}
中序
public static void inOrder(TreeNode node){
//中序遍历,左根右,递归实现
if(node == null){
return;
}else{
//当前节点不是null时,先遍历当前节点的左子树,然后输出当前节点的值,最后遍历当前节点的右子树
inOrder(node.left);
System.out.print(node.val+" ");
inOrder(node.right);
}
}
public static void inOrder2(TreeNode root){
//中序遍历,左根右,递归实现
if(root == null){
return;
}else{
Stack<TreeNode> stack = new Stack<TreeNode>();
//左根右,第一个应该是该二叉树最左下的节点
//从根节点出发,一直寻找节点的左节点,直到最左下的节点
while(root!=null || !stack.isEmpty()){
while(root!=null){
stack.push(root);
root = root.left;
}
//while循环之后,root的值是null,只有当当前节点cur有右子树,root的值会成为右子树的根节点
//现在栈顶元素是最左下的节点,出栈该节点,输出该节点的值,然后看该节点是否存在右节点
//如果存在右节点,继续从该右节点出发,一直寻找节点的左节点,直到最左下的节点
TreeNode cur = stack.pop();
System.out.print(cur.val+" ");
if(cur.right != null){
root = cur.right;
}
}
}
}
后序
public static void postOrder(TreeNode node){
//后序遍历 左右跟
if(node == null){
return;
}else{
postOrder(node.left);
postOrder(node.right);
System.out.print(node.val+" ");
}
}
层序
public static void layerOrder(TreeNode root){
//层序遍历
//利用队列实现
if(root == null){
return;
}else{
Queue<TreeNode> queue = new LinkedBlockingQueue<TreeNode>();
queue.add(root);
while(!queue.isEmpty()){
TreeNode node = queue.remove();
System.out.print(node.val+" ");
if(node.left != null){
queue.add(node.left);
}
if(node.right != null){
queue.add(node.right);
}
}
}
}
二叉树重建
public static TreeNode createBitree(List<Integer> preOrder,List<Integer> inOrder){
int size = preOrder.size();
if(size == inOrder.size() && size>0){
TreeNode root = new TreeNode(preOrder.get(0));//创建当前子树的根节点
//当前子树的根节点在中序遍历序列中的下标,找到该下标之后,该以左的子序列为当前根节点的左子树的中序遍历序列,该以右的子序列为当前根节点的右子树的中序遍历序列
int rootIndex = inOrder.indexOf(preOrder.get(0));
System.out.println("rootIndex:"+rootIndex);
if(rootIndex==0){
//表明当前节点没有左子树
root.setLeft(null);
root.setRight(createBitree(preOrder.subList(rootIndex+1, size), inOrder.subList(rootIndex+1, size)));
}else if(rootIndex == preOrder.size()-1){
//表明当前节点没有右子树
root.setLeft(createBitree(preOrder.subList(1, rootIndex+1), inOrder.subList(0, rootIndex)));
root.setRight(null);
}else{
//当前节点既有左子树又有右子树
root.setLeft(createBitree(preOrder.subList(1, rootIndex+1), inOrder.subList(0, rootIndex)));
root.setRight(createBitree(preOrder.subList(rootIndex+1, size), inOrder.subList(rootIndex+1, size)));
}
return root;
}else{
return null;
}
}
二叉树的计数
具有n个结点、互不相似的二叉树的数目
相似是指二叉树的形态一样,跟结点的值没有关系

参考:https://www.cnblogs.com/gxclmx/p/7485384.html
来源:https://www.cnblogs.com/duanjiapingjy/p/9565013.html