基本概念
每个节点最多两棵子树,次序不可颠倒。`非空二叉树`的第`n`层最多有`2^(n-1)`个节点; 深度为`h`的二叉树最多有`2^h-1`个节点
二叉树分类
所有终端都在同一层次,且非终端结点的度数为2。在满二叉树中若其深度为h,则其所包含的结点数必为2^h-1。通俗来讲,除了最后一层没有任何子节点外,其他节点都有两个子节点
除了最大的层次即成为一颗满二叉树且层次最大那层所有的结点均向左靠齐,即集中在左面的位置上,不能有空位置。对于完全二叉树,设一个结点为i则其父节点为i/2,2i为左子节点,2i+1为右子节点。
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树
它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树
平衡二叉搜索树
二叉树遍历
import java.util.Stack;public class BinaryTree { // 定义节点 class Node { private char key; private Node left; private Node right; public Node (char key) { this(key, null, null); } public Node (char key, Node left, Node right) { this.key = key; this.left = left; this.right = right; } public char getKey() { return key; } public void setKey(char key) { this.key = key; } public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } } private Node root; public BinaryTree (Node root) { this.root = root; } public Node getRoot() { return root; } // 访问节点 public static void visit(Node p) { System.out.println(p.getKey() + " "); } // 递归:前序遍历 public static void preOrder(Node p) { if (p != null) { visit(p); preOrder(p.left); preOrder(p.right); } } // 递归:中序遍历 public static void inOrder(Node p) { if (p != null) { inOrder(p.left); visit(p); inOrder(p.right); } } // 递归:后序遍历 public static void postOrder(Node p) { if (p != null) { postOrder(p.left); postOrder(p.right); visit(p); } } // 非递归:前序遍历(一) public static void iterativePreOrder(Node p) { Stack stack = new Stack (); if (p != null) { stack.push(p); while (!stack.isEmpty()) { p = stack.pop(); visit(p); if (p.getRight() != null) { stack.push(p.getRight()); } if (p.getLeft() != null) { stack.push(p.getLeft()); } } } } // 非递归:前序遍历(二) public static void iterativePreorder2(Node p) { Stack stack = new Stack (); Node node = p; while (node != null || stack.size() > 0) { //压入所有的左节点,压入前访问它。左节点压入完后pop访问右节点。 while (node != null) { visit(node); stack.push(node); node = node.getLeft(); } if (stack.size() > 0) { node = stack.pop(); node = node.getRight(); } } } // 非递归:中序遍历(一) public static void iterativeInorder(Node p) { Stack stack = new Stack (); while (p != null) { while (p != null) { if (p.getRight() != null) stack.push(p.getRight());// 当前节点右子入栈 stack.push(p);// 当前节点入栈 p = p.getLeft(); } p = stack.pop(); while (!stack.empty() && p.getRight() == null) { visit(p); p = stack.pop(); } visit(p); if (!stack.empty()) p = stack.pop(); else p = null; } } // 非递归:中序遍历(二) public static void iterativeInorder2(Node p) { Stack stack = new Stack (); Node node = p; while (node != null || stack.size() > 0) { while (node != null) { stack.push(node); node = node.getLeft(); } if (stack.size() > 0) { node = stack.pop(); visit(node); //与iterativePreorder2比较只有这句话的位置不一样,弹出时再访问。 node = node.getRight(); } } } // 非递归:后序遍历(双栈法) protected static void iterativePostorder4(Node p) { Stack stack = new Stack (); Stack temp = new Stack (); Node node = p; while (node != null || stack.size() > 0) { while (node != null) { temp.push(node); stack.push(node); node = node.getRight(); } if (stack.size() > 0) { node = stack.pop(); node = node.getLeft(); } } while (temp.size() > 0) {//把插入序列都插入到了temp。 node = temp.pop(); visit(node); } } }