上一篇文章主要是介绍了二叉树,用递归的方法实现了二叉树的一些基本操作,这篇文章主要是去补一下前面的内容
- 判断一个树是不是完全二叉树
//判断一个树是不是完全二叉树
public boolean icCompileteTree(TreeNode root){
if (root == null){
return true;
}
Queue<TreeNode> qu = new LinkedList<>();
qu.offer(root);
while (!qu.isEmpty()){//如果队列不为空
TreeNode cur = qu.poll();
if (cur != null){
qu.offer(root.left);
qu.offer(root.right);
}else {
break;
}
}
//判断队列剩下的值有没有空
while (!qu.isEmpty()){
TreeNode top = qu.poll();
if (top != null){
return false;
}
}
return true;
}
完全二叉树,就是判断整个二叉树在节点上面判断整个节点的左子树是否存在,在遍历的时候不能有空的
- 前序遍历二叉树
//非递归实现前序遍历
public List<Character> preorderTraversalNor(TreeNode root) {
List<Character> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {//节点不为空,并且栈不为空
while (cur != null) {
stack.push(cur);
list.add(cur.val);
cur = cur.left;
}
TreeNode top = stack.pop();
cur = top.right;
}
return list;
}
非递归去实现前中后序遍历主要是去从一个栈的方法去实现,主要的逻辑在于判断当节点不为空,并且栈不为空的时候,去进行入队列操作
- 非递归中序遍历
//非递归实现中序遍历
public List<Character> inorderTraversalNor(TreeNode root) {
List<Character> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.pop();
list.add(top.val);
cur = top.right;
}
return list;
}
跟前序遍历的方法和思路是一样的,只不过打印的时候的顺序有不同而已
- 非递归后续遍历
//非递归实现后续遍历
public List<Character> postorderTraversalNor(TreeNode root) {
List<Character> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
TreeNode prev = null;
while (cur != null){
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.peek();
if (top.right == null || top.right == prev){
stack.pop();
list.add(top.val);
prev = top;
}else {
cur = top.right;
}
return list;
}
后续遍历实现是最难的,在打印的时候,要考虑到打印过的节点,如果没有去考虑,很有可能进入打印的死循环,所以定义了一个prev去判断peek的元素是不是被打印过,如果有打印你就pop,再peek,就防止了死循环的出现.
本次分享到这就结束了哈.关于二叉树就到此结束了