二叉树概念
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。
二叉树特点:
- 每个结点最多有两棵子树,即二叉树不存在度大于 2 的结点.
- 二叉树的子树有左右之分,其子树的次序不能颠倒.
两种特殊的二叉树
- 完全二叉树: 完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树.要注意的是满二叉树是一种特殊的完全二叉树
- 满二叉树: 一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果
一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树.
二叉树的遍历
1.NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
2.LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中()间)。
3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
递归方法实现遍历:
public static class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x){
val = x;
}
}
//递归先序遍历二叉树;
public static void preOrderTraversal(TreeNode root){
if(root == null){
return;
}
System.out.print(root.val+" ");
preOrderTraversal(root.left);
preOrderTraversal(root.right);
}
//递归中序遍历二叉树;
public static void inOrderTraversal(TreeNode root){
if(root == null){
return;
}
inOrderTraversal(root.left);
System.out.print(root.val+" ");
inOrderTraversal(root.right);
}
//递归后序遍历二叉树;
public static void postOrderTraversal(TreeNode root){
if(root == null){
return;
}
postOrderTraversal(root.left);
postOrderTraversal(root.right);
System.out.print(root.val+" ");
}
非递归实现遍历:
//非递归先序遍历二叉树;
public static List<Integer> preOrderTraversal(TreeTest.TreeNode root){
//建立一个栈来暂时存放二叉树节点;
LinkedList<TreeTest.TreeNode> stack = new LinkedList<>();
//建立一个链表来存放遍历结果;
LinkedList<Integer> outPut = new LinkedList<>();
if (root == null){
return outPut;
}
stack.add(root);
while (!stack.isEmpty()){
//出栈出链表的最后一个元素放入输出链表中;
TreeTest.TreeNode node = stack.pollLast();
outPut.add(node.val);
//因为是先入后出,所以入栈顺序是右子树优先;
if (node.right != null){
stack.add(node.right);
}
if (node.left != null){
stack.add(node.left);
}
}
return outPut;
}
public static List<Integer> inOderTraversal(TreeTest.TreeNode root){
List<Integer> ret = new ArrayList<>();
Stack<TreeTest.TreeNode> stack = new Stack<>();
TreeTest.TreeNode cur = root;
while (cur != null || !stack.empty()){
while (cur != null){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
ret.add(cur.val);
cur = cur.right;
}
return ret;
}
public static List<Integer> postOrderTraversal(TreeTest.TreeNode root){
//宽度搜索,结果逆序输出就得到后序遍历的结果;
LinkedList<Integer> output = new LinkedList<>();
LinkedList<TreeTest.TreeNode> stack = new LinkedList<>();
if(root == null){
return output;
}
stack.add(root);
while (!stack.isEmpty()){
TreeTest.TreeNode node = stack.pollLast();
output.addFirst(node.val);
if (node.left != null){
stack.add(node.left);
}
if (node.right != null){
stack.add(node.right);
}
}
return output;
}