这是我参与更文挑战的第20天,活动详情查看:更文挑战
树是一种经常用到的数据结构,用来模拟具有树状结构性质的数据集合。
树里的每一个节点有一个根植和一个包含所有子节点的列表。从图的观点来看,树也可视为一个拥有N 个节点和N-1 条边的一个有向无环图。
二叉树 是一种更为典型的树树状结构。如它名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常子树被称作“左子树”和“右子树”。
满二叉树 树的第i层节点数为2^(i-1),则称这棵树为满二叉树。
完全二叉树 设二叉树深度为h,前(h-1)层均被填满(每个父节点均有两个子节点),第h层从左至右,只有最右侧子树未被填满,则称此树为完全二叉树。
堆 是一颗特殊完全二叉树,堆中任意节点的值不大于(小于)其子节点的值。(不大于---最小堆;不小于---最大堆)。可以说,堆就是一棵完全二叉搜索树。
二叉排序树(二叉搜索树) 二叉搜索树是二叉树的一种特殊形式。 二叉搜索树具有以下性质:每个节点中的值必须大于(或等于)其左侧子树中的任何值,但小于(或等于)其右侧子树中的任何值。
平衡二叉树,它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。这个方案很好的解决了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度最好情况和最坏情况都维持在O(logN)。但是频繁旋转会使插入和删除牺牲掉O(logN)左右的时间,不过相对二叉查找树来说,时间上稳定了很多。
红黑树,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。红黑树的特性:
- (1)每个节点或者是黑色,或者是红色。
- (2)根节点是黑色。
- (3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
- (4)如果一个节点是红色的,则它的子节点必须是黑色的。
- (5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
1 深度优先遍历
- 前序遍历:前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if(root == null){
return result;
}
result.add(root.val);
if(root.left != null) result.addAll(preorderTraversal(root.left));
if(root.right != null) result.addAll(preorderTraversal(root.right));
return result;
}
}
- 中序遍历:中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> resultList = new ArrayList<>();
if(root == null){
return resultList;
}
if(root.left != null )resultList.addAll(inorderTraversal(root.left));
resultList.add(root.val);
if(root.right != null)resultList.addAll(inorderTraversal(root.right));
return resultList;
}
}
- 后序遍历:后序遍历是先遍历左子树,然后遍历右子树,最后访问树的根节点。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if(root == null){
return result;
}
if(root.left != null) result.addAll(postorderTraversal(root.left));
if(root.right != null) result.addAll(postorderTraversal(root.right));
result.add(root.val);
return result;
}
}
2 层序遍历(广度优先搜索)
广度优先搜索就是逐层遍历树结构。广度优先搜索是一种广泛运用在树或图这类数据结构中,遍历或搜索的算法。 该算法从一个根节点开始,首先访问节点本身。 然后遍历它的相邻节点,其次遍历它的二级邻节点、三级邻节点,以此类推。当我们在树中进行广度优先搜索时,我们访问的节点的顺序是按照层序遍历顺序的。通常,我们使用队列的数据结构来帮助我们做广度优先搜索。
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if(root == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
List<Integer> levelList = new ArrayList<>();
for(int i = 0;i < size; i++){
TreeNode node = queue.poll();
if(node.left != null){
queue.offer(node.left);
}
if (node.right != null){
queue.offer(node.right);
}
levelList.add(node.val);
}
result.add(levelList);
}
return result;
}
}