引言
在之前的博客中,我向大家分享总结了二叉树的一些特性,如果有兴趣或者遗忘可以再去我主页看看。今天给大家带来 二叉树 的一些基本操作如何实现。
二叉树的实现和基本操作
class TreeNode {
public char val;
public TreeNode left;//左孩子的引用
public TreeNode right;//右孩子的引用
public TreeNode(char val) {
this.val = val;
}
}
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;
}
/**
* 前序遍历:根 -左 -右
* 每棵树都是 根-左-右 的打印方式,于是我们使用递归方法
*/
//前序遍历
void preOrder(TreeNode root) {
if(root == null) {//root为空到头了
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+"");
}
/**
* 层序遍历
* 设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树节点
* 然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点
* 的过程
*/
/**
* 获取树中节点的个数
* 两种方法,1.遍历思路,用计数器count记录节点个数
* 2.子问题思路:root.left+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 size1(TreeNode root) {
if(root == null) {
return 0;
}
return size1(root.left) + size1(root.right) + 1;
}
/**
*获取叶子节点个数
* 遍历思路:遍历到叶子节点,就让计数器++;root.left==null&&root.right==null
* 子问题思路:左树叶子+右树的叶子=整颗树的叶子
*/
//获取叶子节点个数
int count1 = 0;
void getLeafNodeCount(TreeNode root) {
if(root == null) {
return;
}
if(root.left == null && root.right ==null) {
count1++;
}
gerLeafNodeCount1(root.left);
gerLeafNodeCount1(root.right);
}
//子问题思路
int gerLeafNodeCount1(TreeNode root) {
if(root == null) {
return 0;
}
if(root.left == null && root.right ==null) {
//当前的root是叶子节点
return 1;
}
return gerLeafNodeCount1(root.left) + gerLeafNodeCount1(root.right);
}
/**
* 第k层节点个数
* 子问题思路:求第k层 就相当于 就左右树的k-1层
*/
//第k层节点个数
int getKLevelNodeCount(TreeNode root,int k) {
if(root == null || k <= 0) {
return 0;
}
if(k == 1) {
return 1;
}
return getKLevelNodeCount(root.left,k-1) + getKLevelNodeCount(root.right,k-1);
}
/**
* 获取二叉树的高度
* 子问题思路:左 右 树 高度取最大值 + 1(根节点);
* 时间复杂度O(n);//看递归多少次,每个节点都递归
* 空间复杂度O(log以2为底的n次方);--这里写不来---。。。0.0
*/
//获取二叉树的高度
int getHeight(TreeNode root) {
if(root == null) return 0;
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
//三目运算符:如果左树高度 > 右树高度 返回 左树高度+1 反之
return leftHeight > rightHeight ? leftHeight+1 : rightHeight+1;
}
/**
* 检测值为val的元素是否存在
* 先判断 根节点的值 是不是你要找的val,不是先从左边找,找不到再去右边找,找到就返回
*/
//检测值为val的元素是否存在
TreeNode find(TreeNode root,char val) {
if (root == null) return null;
if (root.val == val) {
return root;
}
TreeNode ret = find(root.left,val);
if(ret != null) {
return ret;
}
ret = find(root.right,val);
if(ret != null) {
return ret;
}
return null;
}
/**
* 判断一棵树是不是完全二叉树
* 使用队列:先判断root为不为空 不为空 将root 入队列 弹出 再将 root的左右节点入节点
* 如此循环 如果最后队列里 都为空 那么就是完全二叉树 (建议画个图很好理解)
*/
//判断一颗树是不是完全二叉树
boolean isCompleteTree(TreeNode root) {
if(root == null) return true;//空树也是完全二叉树
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode cur = queue.poll();
if(cur != null) {
queue.offer(cur.left);
queue.offer(cur.right);
}else {
break;
}
}
while (!queue.isEmpty()) {
TreeNode top = queue.peek();
if(top != null) {
return false;
}
queue.poll();
}
return true;
}
}
|