1、二叉树基本概念:二叉树是每个节点最多有两个子树的有序树。通常子树的根被称作“左子树”和“右子树”。
2、二叉树的单个结点:左子树、右子树、值。
class TreeNode {//一个结点的构造方法
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode (char val) {
this.val = val;
}
}
3、二叉树:为了方便调试,我们用简单方法建立一个二叉树,该二叉树如下图所示。
public class BinaryTree {
public TreeNode createTree() {
TreeNode A = new TreeNode('A');
TreeNode B = new TreeNode('B');
TreeNode C = new TreeNode('C');
TreeNode D = new TreeNode('D');
TreeNode E = new TreeNode('E');
TreeNode F = new TreeNode('F');
TreeNode G = new TreeNode('G');
TreeNode H = new TreeNode('H');
A.left = B;
A.right = C;
B.left = D;
B.right = E;
C.left = F;
C.right = G;
E.right = H;
return A;
}
4、二叉树的前中后序遍历:每次把根结点的左右子树当作新的根节点递归遍历,当根节点为空时说明此时已经达到了树的尽头。
void preOrder(TreeNode root) {//前序遍历,遍历顺序根左右,每次遇到根节点时打印,遍历到根节点为空时返回,
if(root == null) {
return;
}
System.out.print(root.val + " ");
preOrder(root.left);
preOrder(root.right);
}
void inOrder(TreeNode root) {//中序遍历
if(root == null) {
return;
}
inOrder(root.left);
System.out.print(root.val + " ");
inOrder(root.right);
}
void postOrder(TreeNode root) {//后序遍历
if(root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
System.out.print(root.val + " ");
}
5、求所有结点:①遍历:在方法外定义一个变量count=0,每当递归一次时如果root不为0,那么这个结点就存在,此时count++②子问题:每次递归返回size0(root.left) + size0(root.right) + 1
int count = 0;
int size(TreeNode root) {//遍历求所有结点的方法
if (root == null) {
return 0;
}
count ++;
size(root.left);
size(root.right);
return count;
}
int size0(TreeNode root) {//子问题求所有结点的方法
if (root == null) {
return 0;
}
return size0(root.left) + size0(root.right) + 1;//
}
6、求所有叶子结点:和求所有结点类似,但是要判断这个结点的孩子结点是否都为空,是的话这个结点就是叶子结点。
int leaf = 0; int getLeafNodeCount(TreeNode root) {//遍历求叶子结点的方法 if (root == null) { return 0; } if (root.left == null && root.right == null) { leaf ++; } getLeafNodeCount(root.left); getLeafNodeCount(root.right); return leaf; } int getLeafNodeCount0(TreeNode root) {//子问题求叶子结点的方法 if(root == null) { return 0; } if (root.left == null && root.right == null) { return 1; } return getLeafNodeCount0(root.left) + getLeafNodeCount0(root.right); }
7、求第k层的结点个数:
int getKLevelNodeCount(TreeNode root, int k ) {//求k层结点的个数
if (root == null || k < 1) {//终止条件①当这棵树没有子树无法继续,②当这棵树有子树但是已经到k了没必要继续
return 0;
}
if (k == 1) {//根据规律,当K=1时说明达到了给出的条件
return 1;
}
return getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.right, k - 1);
}
int getHeight(TreeNode root) { //获取二叉树的高度
if (root == null) {
return 0;
}
return (getHeight(root.left) > getHeight(root.right)) ? getHeight(root.left) + 1: getHeight(root.right) + 1;
}
8、值为value的结点是否存在:
TreeNode find(TreeNode root, char value) {//值为value的元素是否存在
if (root == null) {
return null;
}
if (root.val == value) {
return root;
}
TreeNode ret = find(root.left, value);
if (ret != null) {
return ret;
}
ret = find(root.right, value);
if (ret != null) {
return ret;
}
return null;
}
9、是否为完全二叉树: 判断是否为完全二叉树,将二叉树左右两边的结点放入队列,队列每次弹出一个元素,此元素不为空则将他的两个孩子结点放入队列,继续执行循环弹出下一个元素,最后会得到一个队列,如果队列里有非空元素则不是完全二叉树。
boolean isCompleteTree(TreeNode root) {//判断是否为完全二叉树,将二叉树左右两边的结点放入队列,队列每次弹出一个元素。
if (root == null) return true; //此元素不为空则将他的两个孩子结点放入队列,继续执行循环弹出下一个元素。
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
TreeNode cur;
int size = size(root);
while (!queue.isEmpty()) {
cur = queue.poll();
if (cur != null) {
queue.offer(cur.left );
queue.offer(cur.right);
} else {
break;
}
}
while (!queue.isEmpty()) {//最后判断队列里如果有不为空的元素那么不是完全二叉树
if (!(queue.poll() == null)) {
return false;
}
}
return true;
}