赞
踩
满二叉树:如果一颗二叉树只有度为0的节点和度为2的节点,并且度为0的结点在同一层上,那么这颗树就是满二叉树(度:表示子节点的个数)
如果一颗满二叉树的深度为k 那么他的节点个数就是2^k-1
完全二叉树:除了最低层的结点可能没有填满外,其余各层节点数都大道 最大值 并且最低层的节点都集中在最左边的若干位置
如果最底层为h层 那应该包含 1~2^(h-1)个节点
二叉搜索树也成为二叉排序树或者二叉查找树
满足以下性质:
1、 非空左子树的键值都小于根节点;
2、 非空右子树的键值都大于根节点
3、 它的左右子树也是搜索树
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具 有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
顺序存储有以下特点:如果父节点的对应数组下标为i 那么他的左孩子就是2i+1 右孩子就是i2+1;
二叉树每个结点都是由 键值和左右孩子组成(叶子结点没有左右子树);
因此一个结点TreeNode 包括了 三个属性 分别是val 表示键值 和左孩子left 右孩子right
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val,TreeNode left,TreeNode right ){
this.val=val;
this.left=left;
this.right=right;
}
}
1、 前序遍历:中左右
2、 中序遍历:左中右
3、 后序遍历:左右中
public void preorder(TreeNode root){//前序遍历
if(root!=null)
{
System.out.print(root.data+" ");
preorder(root.left);
preorder(root.right);
}
}
public void midorder(TreeNode root){//中序遍历
if(root!=null)
{
midorder(root.left);
System.out.print(root.data+" ");
midorder(root.right);
}
}
public void postorder(TreeNode root){//后序遍历
if(root!=null)
{
postorder(root.left);
postorder(root.right);
System.out.print(root.data+" ");
}
}
总结 递归法 前序中序后序遍历的区别就主要在于 print的位置;
迭代法前中后序 遍历主要是利用栈来实现的
前序遍历:中左右首先处理根节点 那么就先将根节点入栈 随后处理左结点那么将右子树入栈;为什么处理与入栈顺序不同呢?
因为栈是先进后出 只有这样处理我出栈的顺序才是中左右
public static List<Character> preorderByStack(TreeNode root) { List<Character> ans = new ArrayList<>(); if(root==null){ return ans; } Stack<TreeNode> st = new Stack<>(); st.add(root); while(!st.isEmpty()) { TreeNode tmp = st.pop(); ans.add(tmp.val); if(tmp.right != null) st.add(tmp.right); if(tmp.left !=null) st.add(tmp.left); } return ans; }
后序遍历与前序遍历类似,简单来说就是把前序遍历的“中” 放到最后,但是要注意我们使用的是栈来模拟因此我们要调整前序遍历变成中右左的遍历顺序,然后反转rans数组,输出结果就是我们想要的左右中了。
public static List<Character> postOrderByStack(TreeNode root) { List<Character> ans = new ArrayList<>(); if(root == null) return ans; Stack<TreeNode> st = new Stack<>(); st.add(root); while(!st.isEmpty()) { TreeNode tmp = st.pop(); ans.add(tmp.val); if(tmp.left!=null) st.add(tmp.left); if(tmp.right!=null) st.add(tmp.right); } Collections.reverse(ans); return ans; }
中序遍历相较于前序遍历和后序遍历更加复杂一下:中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进ans数组中),这就造成了处理顺序和访问顺序是不一致的。
所以我们针对这种情况那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。
public static List<Character> midOrderByStack(TreeNode root) { List<Character> ans = new ArrayList<>(); if(root == null) return ans; Stack<TreeNode> st = new Stack<>(); TreeNode cur = root; while(cur!=null||!st.isEmpty()) { if(cur!=null){ st.push(cur); cur = cur.left; } else { cur = st.pop(); ans.add(cur.val); cur = cur.right; } } return ans; }
public void levelorderByQueue(TreeNode root){
Queue<TreeNode> q=new LinkedList<>();
if(root==null) return;
q.offer(root);
while(!q.isEmpty())
{
TreeNode head=q.poll();
System.out.print(head.data+" ");
if(head.left!=null)
q.offer(head.left);
if(head.right!=null)
q.offer(head.right);
}
}
public void levelorderBydfs(TreeNode node, Integer deep) {
List<List<Integer>> resList = new ArrayList<List<Integer>>();
if (node == null) return;
deep++;
if (resList.size() < deep) {
List<Integer> item = new ArrayList<Integer>();
resList.add(item);
}
resList.get(deep - 1).add(node.val);
levelorderBydfs(node.left, deep);
levelorderBydfs(node.right, deep);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。