二叉树的存储方式和遍历方式
Posted dxj1016
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的存储方式和遍历方式相关的知识,希望对你有一定的参考价值。
二叉树的存储方式
链式存储
链式存储就是使用指针,通过指针把分布在散落在各个地址的结点串联一起。
链式存储的二叉树数据结构:
public 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;
顺序存储
顺序存储的方式是用数组,顺序存储的元素在内存是连续分布的
用数组来存储二叉树如何遍历的?
如果父结点的数组下标是i,那么他的左孩子就是i*2+1,右孩子就是i * 2+2;
二叉树的遍历方式
遍历方式
- 深度优先遍历:先往深走,遇到叶子结点再往回走
- 前序遍历(递归法,迭代法)
- 中序遍历(递归法,迭代法)
- 后序遍历(递归法,迭代法)
- 广度优先遍历:一层一层的去遍历
- 层次遍历(迭代法)
在深度优先遍历中:有三个顺序,前中后序遍历, 有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。
深度优先遍历的实现
144. 二叉树的前序遍历
/**
* 递归排序--前序遍历
* @param head
*/
ArrayList<Integer> preOrderReverse(Node head)
ArrayList<Integer> result=new ArrayList<Integer>();
preOrderRecur(head,rusult);
return result;
/**
* 前序遍历的实现
* @param head
*/
public static void preOrderRecur(Node head,ArrayList<Integer> result)
if (head == null)
return;
result.add(head.value);
preOrderRecur(head.left,result);
preOrderRecur(head.right,result);
/**
* 非递归排序--前序遍历
* 前头结点进栈,然后打印,然后右孩子进栈,然后左孩子进栈。
* 前序遍历是中左右,先访问的是中间结点,要处理的元素也是中间结点
* 要访问的元素和要处理的元素顺序是一致的,都是中间结点。
* @param head
*/
public static List<Integer> preOrderUnRecur(Node head)
List<Integer> result=new ArrayList<>();
System.out.println("pre-order: ");
if (head != null)
Stack<Node> stack = new Stack<Node>();
stack.add(head);
while (!stack.isEmpty())
head = stack.pop();
result.add(head.value);
if (head.right != null)
stack.push(head.right);
if (head.left != null)
stack.push(head.left);
return result;
94. 二叉树的中序遍历
/**
* 递归排序--中序遍历
* @param head
*/
public List<Integer> InOrderReverse(Node head)
List<Integer> result=new ArrayList<Integer>();
inOrderRecur(head,rusult);
return result;
/**
* 中序遍历的实现
* @param head
*/
public static void inOrderRecur(Node head,List<Integer> list)
if (head == null)
return;
inOrderRecur(head.left,list);
list.add(head.val);
inOrderRecur(head.right,list);
/**
* 非递归排序--中序遍历
* 一开始栈为空,看栈和二叉树是否为空
* 如果二叉树不为空,就头结点进栈,接着左孩子进栈
* 如果二叉树为空,那么出栈并打印,然后右孩子进栈
* 中序遍历是左中右,先访问二叉树顶部结点,然后一层一层向下访问,直到到达树左边的最底部,再开始处理结点(也就是把结点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的
* @param head
*/
public static List<Integer> inOrderUnRecur(Node head)
List<Integer> result=new ArrayList<>();
System.out.println("in-order");
if (head != null)
Stack<Node> s = new Stack<>();
while (!s.isEmpty() || head != null)
if (head != null)
s.push(head);
head = head.left;
else
head = s.pop();
result.add(head.value);
head = head.right;
return result;
145. 二叉树的后序遍历
/**
* 递归排序--后序遍历
* @param head
*/
public List<Integer> PosOrderReverse(Node head)
List<Integer> result=new ArrayList<Integer>();
PosOrderRecur(head,rusult);
return result;
/**
* 后序遍历的实现
* @param head
*/
public static void posOrderRecur(Node head)
if (head == null)
return;
posOrderRecur(head.left,result);
posOrderRecur(head.right,result);
list.add(head.value);
/**
* 非递归排序--后序遍历
* 头结点进栈,然后看栈是否为空,不为空就出栈,并且进入第二个栈
* 然后看左孩子进栈,然后右孩子进栈
* 最后第二个栈全部出栈,并打印
* @param head
*/
public static List<Integer> posOrderUnRecur(Node head)
List<Integer> result=new ArrayList<>();
System.out.println("pos-order: ");
if (head != null)
Stack<Node> s1 = new Stack<>();
Stack<Node> s2 = new Stack<>();
s1.push(head);
while (!s1.isEmpty())
head = s1.pop();
s2.push(head);
if (head.left != null)
s1.push(head.left);
if (head.right != null)
s1.push(head.right);
while (!s2.isEmpty())
head = s2.pop();
result.add(head.value);
return result;
*589. N 叉树的前序遍历
/*
// Definition for a Node.
class Node
public int val;
public List<Node> children;
public Node()
public Node(int _val)
val = _val;
public Node(int _val, List<Node> _children)
val = _val;
children = _children;
;
*/
class Solution
public List<Integer> preorder(Node root)
Stack<Node> stack=new Stack<>();
List<Integer> list=new LinkedList<>();
if(root==null)
return list;
stack.push(root);
while(!stack.isEmpty())
Node node=stack.pop();
list.add(node.val);
Collections.reverse(node.children);
stack.addAll(node.children);
return list;
*590. N 叉树的后序遍历
/*
// Definition for a Node.
class Node
public int val;
public List<Node> children;
public Node()
public Node(int _val)
val = _val;
public Node(int _val, List<Node> _children)
val = _val;
children = _children;
;
*/
class Solution
List<Integer> list = new ArrayList<Integer>();
public List<Integer> postorder(Node root)
if (root == null)
return list;
for (Node node : root.children)
postorder(node);
list.add(root.val);
return list;
广度优先遍历的实现
102. 二叉树的层序遍历
/**
* Definition for a binary tree node.
* public 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;
*
*
*/
class Solution
public List<List<Integer>> levelOrder(TreeNode root)
List<List<Integer>> lists=new ArrayList<>();
if(root==null)
return lists;
List<TreeNode> stack=new ArrayList<>();
stack.add(root);
while(!stack.isEmpty())
int size=stack.size();
List<Integer> list=new ArrayList<>();
for(int i=0;i<size;i++)
TreeNode remvoe=stack.remove(0);
list.add(remvoe.val);
if(remvoe.left!=null)
stack.add(remvoe.left);
if(remvoe.right!=null)
stack.add(remvoe.right);
lists.add(list);
return lists;
107. 二叉树的层序遍历 II
思路:相对于102.二叉树的层序遍历,就是最后把数组反转一下就可以了。也可以直接在加入数组的时候从后面加
/**
* Definition for a binary tree node.
* public 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;
*
*
*/
class Solution
public List<List<Integer>> levelOrderBottom(TreeNode root)
List<List<Integer>> lists=new LinkedList<>();
if(root==null)
return lists;
List<TreeNode> listTree=new LinkedList<>();
listTree.add(root);
while(!listTree.isEmpty())
int size=listTree.size();
List<Integer> list=new ArrayList<>();
for(int i=0;i<size;i++)
TreeNode node=listTree.remove(0);
list.add(node.val);
if(node.left!=null)
listTree.add(node.left);;
if(node.right!=null)
listTree.add(node.right);
lists.add(0,list);
return lists;
199. 二叉树的右视图
思路:层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。
/**
* Definition for a binary tree node.
* public 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;
*
*
*/
class Solution
public List<Integer> rightSideView(TreeNode root)
List<Integer> list=new ArrayList<>();
if(root==null)
return list;
List<TreeNode> listTree=new ArrayList<>();
listTree.add(root);
while(!listTree.isEmpty())
int size=listTree.size();
for(int i=0;i<size;i++)
TreeNode remove=listTree.remove(0);
if(i==size-1)
list.add(remove.val);
if(remove.left!=null)
listTree.add(remove.left);;
if(remove.right!=null)
listTree.add(remove.right);
return list;
637. 二叉树的层平均值
思路:本题就是层序遍历的时候把一层求个总和在取一个均值。
/**
* Definition for a binary tree node.
* public 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;
*
*
*/
class Solution
public List<Double> averageOfLevels(TreeNode root)
List<TreeNode> stack=new LinkedList<>();
List<Double> list=new LinkedList<>();
if(root==null二叉树的遍历与建立