学习二叉树有感,作者简单的对二叉树基础进行回忆。
二叉树其实就是简单的一颗倒过来的树,根在最上面,其他节点一节一节往下衍生,详情可以自行搜索图片看。
在用JAVA写代码,我发现其实跟C语言的结构很像,学完JavaSE,其实还是有点难懂,但如果去写代码在去和C语言进行对比发现,其实其中的思想和结构是不变的。
这里从零开始搭建,先创建一个class 树类,然后在这个类当中在创建一个树节点,class TreeNode 由自己定义的一个节点,这里使用用孩子表示法,在TreeNode当中有树的值(value),左孩子(left)和右孩子(right),然后在创建构造方法,public TreeNode(char val)调用this去给value 赋值。
还未用递归的方式去创建二叉树,先从最简单的方法去创建二叉树,先去创建一个个节点,在用手动的方式去连接各各节点,
先创建一个创建二叉树的方法,public TreeNode creatTree(){
TreeNode A = new TreeNode('A');
TreeNode B = new TreeNode('B');
TreeNode C = new TreeNode('C');
//然后调用节点中的left和right,
A.left = B;
A.right = C;
//最后返回根节点A。
return A;
}
这样最简单的二叉树搭建成功。
在创建一个数据结构的时候,要提前规划,这个数据结构当中最基本享有哪些方法,
二叉树当中则有创建二叉树,然后便是前序遍历,中序遍历,后序遍历,二叉树当中有多少节点,有多少个叶子节点,二叉树有多少层,二叉树某一层的节点有多少,二叉树当中是否有某个值为X的节点等等。
二叉树最简便的方法是使用递归,任何二叉树都可以分为根节点、左子树和右子树。通过不断递归的方式,走完整个二叉树,
比如三个遍历,
前序遍历(preOrderTraversal):根(调用一次递归),左子树,右子树。
中序遍历(postOrder):左子树,根,右子树。
后续遍历(inOrder):左子树,右子树,根。
举个前序遍历的例子:
public void preOrder(TreeNode root){
if(root == null){
return;
}
System.out.print(root.val);//根
preOrder(root.left);//左子树
preOrder(root.right);//右子树
}
而中序和后序遍历,只是在前序遍历的基础上换个位置即可。
如果想要知道二叉树当中有多少个节点,则可以通过一次遍历便可计算出来。
用递归的方式可以这样思考,二叉树由根节点、左子树和右子树组成,实际上我们可以理解为
左子树的所有节点加上右子树的所有节点在加上根节点,就可以算出整颗二叉树有多少个节点。
int size(TreeNode root){
if(root == null){
return 0;
}
retrun size(root.left) + size(root.right) +1;
}
如何计算二叉树的叶子节点有多少个呢。叶子节点的定义是左孩子和右孩子都是null,度为零的节点,因此继续使用递归的思维,直接去计算左孩子和右孩子的叶子节点。
int leafCount(TreeNode root){
if(root null){
return 0;
}
if(root.left == null && root.right == null){
return 1;
}
return leafCount(root.left)+leafCount(root.right);
}
二叉树有多高呢,我们依旧使用递归的方法去思考,一个最简单的二叉树的高度为两层,左孩子和右孩子同为一层,加上根节点,所以是两层,通过这样思考则可以将一颗很大的二叉树全部分散为一颗颗最简单的二叉树,如果没有孩子节点的话高度就是一层。通过不断递归,会出现高度不对等,比如左边的高度比右边高,或者右边的高度比左边高,因为二叉树的性质,不是满二叉树的话,就会出现这样的情况,那么高度比较高的那一边再加上根节点的一层,才是这颗二叉树的高度,通过不断递归,最终得到整颗二叉树的高度。
int getHeight(TreeNode root){
if(root == null){
return 0;
}
int leftHeight = getHeight(root.left);
int rightHeight = getHeight(root.right);
return leftHeight > rightHeight ? leftHeight +1 : rightHeight + 1;
}
第二种纯递归实现,但是时间复杂的比较高
int getHeight1(TreeNode root){
if(root == null){
return 0;
}
return getHeight1(root.left) > getHeight1(root.right) ? getHeight1(root.left);+1 : getHeight1(root.right)+ 1;
}
既然知道了二叉树有多高,那么在某一高度的二叉树有多少个节点呢,我们依旧可以通过递归的方式去思考,最简单的二叉树只有两层高,第一层和第二层,一样如果我们想要第一层的数量,H=1,那么只有根节点一个,所以返回1;如果是H=2,那么递归到左子树,H-1 =1,这样相当于H又变成了1,返回左子树的根节点1个,右子树同理,这样H=2时,有两个节点。
int HeightCount (TreeNode root,int h){
if(root == null){
return 0;
}
if(h == 1){
return 1;
}
return HeightCount(root.left,h-1) + HeightCount(root.right,h-1);
}
最后如果我们想要确认二叉树当中是否有我们想要的节点,可以去查询当中是否有,通过递归对比最后返回我们想要的节点。
TreeNode find(TreeNode root, char val){
if(root == null){
return null;
}
if(root.val == val){
return root;
}
TreeNode ret1 = find(root.left, val);
if(ret1 != null){
return ret1;
}
TreeNode ret2 = find(root.right, val);
if(ret2 != null){
return ret2;
}
return null;
这些只是最基础的二叉树功能。但是由于没有配图,所以会比较抽象,所以只能作为复习使用。