层次遍历二叉树
二叉树并不难,主要是队列的操作比较陌生(之前惯用栈),在这里记录一下
层次遍历即一层一层地读出来,很容易理解
我这里用队列存储结点,每层循环后逐个弹出,进行一个结点进行迭代
class Solution {
public int[] levelOrder(TreeNode root) {
List<Integer> list=xiajibaxie(root);
int arr[]=new int[list.size()];
for (int i = 0; i <list.size() ; i++) {
arr[i]=list.get(i);
}
return arr;
}
public List<Integer> xiajibaxie(TreeNode root){
List<Integer> list=new ArrayList<>();
Queue<TreeNode> deque=new LinkedList<>();//建立队列,LinkedList是双向链表,它既可以
// 充当队列,也可以当作栈使用
TreeNode curr=root;
while(curr!=null){
list.add(curr.val);
TreeNode curr_left=curr.left;
TreeNode curr_right=curr.right;
if(curr_left!=null){
deque.add(curr_left);
}
if(curr_right!=null){
deque.add(curr_right);
}
curr=deque.poll();//弹出,进行下一层的遍历
}
return list;
}
}
队列的基本操作有(转载)
public static void main(String[] args) {
Queue<String> que = new LinkedList<>(); // 基于链表的Linked 不能用基于数组的 ArrayList
que.add("1");
que.add("2");
que.add("3");
que.add("5");
que.add("4");
System.out.println(que);
que.offer("7");
que.offer("8");
que.offer("9");
System.out.println(que);
String element = que.element(); //返回第一个元素
System.out.println(element+"此时的大小是"+que.size());
String peek = que.peek();
System.out.println("第一个元素"+peek); //返回第一个元素
String poll = que.poll(); 返回第一个元素,并在队列中删除
String poll2 = que.poll();
System.out.println(poll);
System.out.println(poll2);
}
}
————————————————
版权声明:本文为CSDN博主「爱吃早餐的程序员」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39076203/article/details/110041520
其中常用的便是isEmpty(),add(),peek(),poll()
.在前中后序遍历二叉树,则需要用到栈进行迭代,或者用递归处理
前中后序遍历直观地来看
此图为转载
先(根)序遍历(根左右):A B D H E I C F J K G
中(根)序遍历(左根右) : D H B E I A J F K C G
后(根)序遍历(左右根) : H D I E B J K F G C A
前序遍历二叉树
前序遍历,先父节点,在左子树,再右子树
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list=new ArrayList<>();
Stack<TreeNode> stack=new Stack<>();
TreeNode cur=root;
while(cur!=null || !stack.isEmpty()){
if(cur!=null){
list.add(cur.val);
stack.push(cur);
cur=cur.left;
}else{
cur=stack.pop();
cur=cur.right;
}
}
return list;
}
}
中序遍历二叉树,先左子树,再父节点,再右子树
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();//存放节点的链表
Stack<TreeNode> stack = new Stack<>();//中转栈
TreeNode curr=root;
while(!stack.isEmpty()||curr!=null){
if(curr!=null){
stack.push(curr);
curr=curr.left;先到左子树的底端
}
else{
curr=stack.pop();
list.add(curr.val);//左边遍历到底再添加,说到底前序遍历是左节点,父节点,右节点
curr=curr.right;
}
}
return list;
}
}
后序遍历二叉树 先左,再右,再父结点
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<Integer>();
if(root==null) return res;
ArrayDeque<TreeNode> s=new ArrayDeque<>();
TreeNode node=root;
while(!s.isEmpty()||node!=null){
if(node!=null){
s.push(node);
res.add(node.val);
node=node.right;
}
else{
node=s.pop();
node=node.left;
}
}
Collections.reverse(res);
return res;
}
}
9.28更新
层次遍历二叉树,将每一层结点val装到不同的链表里面,题目
代码如下,思路与层次遍历没有什么差别
public class Solution {
/**
* 从上至下一层一层打印,称之为广度优先搜索,BFS;可以借助队列的先进先出特性来做
*/
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> lists = new ArrayList<>();
// 使用队列先进先出的特性
Queue<TreeNode> queue = new LinkedList<>();
if (root != null) {
// 先将根节点加入队列
queue.add(root);
}
while (!queue.isEmpty()) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = queue.size() - 1; i >= 0; i--) {//size在循环结束之前并不会发生改变
TreeNode node = queue.poll();
list.add(node.val);
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
lists.add(list);
}
return lists;
}
}
10.13日更新 morris中序遍历,降低复杂度,这块说实话目前没太搞明白,先码住
Morris 遍历算法整体步骤如下(假设当前遍历到的节点为 x):
如果 x 无左孩子,则访问 x 的右孩子,即 x=x.right。的右孩子是否为空,进行如下操作。
如果 x 有左孩子,则找到 x 左子树上最右的节点
如果 predecessor 的右孩子为空,则将其右孩子指向 x,然后访问 x 的左孩子,即 x=x.left。
如果 predecessor 的右孩子不为空,则此时其右孩子指向 x,说明我们已经遍历完 x 的左子树,我们将predecessor 的右孩子置空,然后访问 x 的右孩子,即 x=x.right。