知识点:
1.前驱只有一个,后继有N个
2.满二叉树,k层,结点总数2^k-1个
3.性质:
1) 一棵二叉树,叶结点数n0个,度为2的非叶结点数n2个 => n0 = n2+1
完全二叉树
2)n个结点的完全二叉树的深度k 为log(n+1) 上取整
3)从上至下,从左至右,的顺序 对所有结点从0开始编号:
`父亲节点为下标 -> 左孩子2i+1,右孩子2i+2
`孩子(左/右)节点下标i -> 父亲(i-1)/2
4.根据前序,中序创建一棵树(后面有一道相关编程题):
通过前序来找根节点,中序找前序找的根节点的下标,左边为左树,右边为右树
5.二叉树是非线性数据结构
相关习题:
1.遍序递归:
子问题思路,遍历思路.注意list创建问题. 比较简单,不多说
import java.util.ArrayList;
import java.util.List;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Main {
List<Integer> list = new ArrayList<Integer>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root == null){
return list;
}
list.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return list;
}
public List<Integer> preorderTraversal1(TreeNode root) {
List<Integer> list1 = new ArrayList<>();
if(root == null){
return list1;
}
list1.add(root.val);
List<Integer> leftNode = preorderTraversal(root.left);
list1.addAll(leftNode);
List<Integer> rightNode = preorderTraversal(root.right);
list1.addAll(rightNode);
return list1;
}
}
2.二叉树的最近公共祖先:
方法一:列出公共祖先的几种情况:1.一个为root -> root. 2.左树两个->左树 3.右树两个 -> 右树 4.左树一个,右树一个->公共祖先root
方法二: 用栈,把 p的所有路径存一份 q的所有路径存一份 让size相等,再一起出栈,值相同的时候,就是公共祖先
难点-怎么存入栈?--不空则入栈,比较值是否为p/q是返回true,递归左,递归右,若是true`返回,最后真的不是,让它出栈,返回false
import java.util.Stack;
class TreeNode{
char val;
TreeNode left;
TreeNode right;
public TreeNode(char val){
this.val = val;
}
}
public class Main {
//方法一:公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null){
return null;
}
if (root == p || root == q){
return root;
}
TreeNode rootLeft = lowestCommonAncestor(root.left,p,q);
TreeNode rootRight = lowestCommonAncestor(root.right,p,q);
if(rootLeft != null && rootRight != null){
return root;
}else if(rootLeft != null){
return rootLeft;
}else{
return rootRight;
}
}
//方法二:公共祖先 利用栈
public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || p == null || q == null){
return null;
}
Stack<TreeNode> s1 = new Stack<>();
getPath(root,p,s1);
Stack<TreeNode> s2 = new Stack<>();
getPath(root,q,s2);
int size1 = s1.size();
int size2 = s2.size();
if(size1>size2){
int tmp = size1-size2;
while (tmp > 0){
s1.pop();
tmp--;
}
}else{
int tmp = size2-size1;
while (tmp > 0){
s2.pop();
tmp--;
}
}
while (!s1.isEmpty() && !s2.isEmpty()){
if(s1.peek() == s2.peek()){
return s1.peek();
}else{
s1.pop();
s2.pop();
}
}
return null;
}
public static boolean getPath(TreeNode root, TreeNode node, Stack<TreeNode> s){
if(root == null || node == null){
return false;
}
s.push(root);
if(root == node){
return true;
}
boolean ret1 = getPath(root.left,node,s);
if(ret1){
return true;
}
boolean ret2 = getPath(root.right,node,s);
if(ret2){
return true;
}
s.pop();
return false;
}
}
3.输入一棵搜索二叉树,将该二叉树转化为一个双向链表:
第一步:排序:利用中序遍历
第二步:双向链表: 用pre 将他们串起来
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Main {
public TreeNode prev;
public void ConvertChild(TreeNode root) {
if(root == null) return;
ConvertChild(root.left);
root.left = prev;
if(prev != null){
prev.right = root;
}
prev = root;
ConvertChild(root.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null){
return null;
}
ConvertChild(pRootOfTree);
TreeNode head = pRootOfTree;
while(head.left != null){
head = head.left;
}
return head;
}
}
4.根据一棵树的前序遍历和中序遍历构造二叉树
第一步:把前序遍历的值先构建根节点
第二步:在中序遍历数组,找到根节点的位置i,有begin,end控制遍历长度
第三步:分别构建左树和右树
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public int indix;
public int findRootIndix(int val, int[] inorder, int begin, int end){
for (int i = begin; i <= end ; i++) {
if(val == inorder[i]){
return i;
}
}
return -1;
}
public TreeNode buildTreeChild(int[] preorder, int[] inorder, int begin, int end) {
if(begin > end){
return null;
}
TreeNode root = new TreeNode(preorder[indix]);
int rootIndix = findRootIndix(preorder[indix],inorder,begin,end);
indix++;
root.left = buildTreeChild(preorder,inorder,begin,rootIndix-1);
root.right = buildTreeChild(preorder,inorder,rootIndix+1, end);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTreeChild(preorder,inorder,0,inorder.length-1);
}
}
这些题都挺经典的,可以去力扣啊,牛客啊 找一找 坐一坐 冲啊!!!小伙伴们,一起为梦想努力吧