一、分类
1、二叉查找树
(1)左子树不为空,并且左子树所有结点的值小于根节点的值
(2)右子树不为空,并且右子树所有节点的值大于根节点的值
(3)左右子树也分别是二叉排序树
(4)没有键值相等的结点
2、平衡二叉树(AVL)
左右两个子树的高度差不超过一,并且左右两个子树也都是平衡二叉树
3、红黑树
(1)每个结点要么是红的要不是黑的
(2)根结点必须是黑的
(3)叶子结点必须是黑的
(4)如果父节点是红点,那么两个子结点是黑的
(5)对应每个结点从该结点到其子孙结点的所有路径包含相同的数目
4、B-树
是一种多路搜索树
(1)拥有至少两个子女
(2)每个非根结点包含的关键字个数j满足 m/2-1 < j < m - 1
(3)除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树k的个数满足 m/2 <= k <= m
(4)所有叶子结点都位与同一层
5、B+树
是B-树的一种变形
6、字典树
是一种Hash树的变种,典型的应用是用户统计、排序和保存大量字符串,所以经常被搜索引擎用于词频的搜索与文本统计
利用字符串的公共前缀来节约存储空间,最大限度减少无谓的字符串比较,查询效率比Hash表要高
字典树和字典是很相似的,先查找第一个字母是否在字典的第一层,如果没有就是没有找到了
二、函数
如下是二叉树的类结构
class TreeNode{
int val;
//左孩子
TreeNode left;
//右孩子
TreeNode right;
}
1、求二叉树的最大深度
//1、求二叉树的最大深度
public static int maxDeep(TreeNode node){
if(node == null){
//这是截止条件
return 0;
}
int left = maxDeep(node.left);
int right = maxDeep(node.right);
return Math.max(left, right) + 1;
}
2、求二叉树的最小深度
//2、求二叉树的最小深度
public static int minDeep(TreeNode node){
if(node.left == null && node.right == null){
//其实这个截止条件也是可以的,和上的类似
return 1;
}
int left = minDeep(node.left);
int right = minDeep(node.right);
return Math.min(left, right) + 1;
}
3、二叉树的结点个数
//3、求二叉树的结点个数
public static int numOfTreeNode(TreeNode node){
if(node == null){
return 0;
}
int left = numOfTreeNode(node.left);
int right = numOfTreeNode(node.right);
return left + right + 1;
}
4、二叉树中叶子结点的个数
//4、求二叉树中叶子结点的个数
public static int numOfChildNode(TreeNode node){
if(node == null){
return 0;
}
if(node.left == null && node.right == null){
return 1;
}
int left = numOfChildNode(node.left);
int right = numOfChildNode(node.right);
return left + right;
}
5、二叉树中k层的结点数
//5、求二叉树第k层的结点数
public static int numsOfkLevelTreeNode(TreeNode node, int k){
if(node == null || k < 1){
return 0;
}
if(k == 1){
return 1;
}
int left = numsOfkLevelTreeNode(node, k-1);
int right = numsOfkLevelTreeNode(node, k-1);
return left + right;
}
6、判断是否是平衡二叉树
//6、判断二叉树是否是平衡二叉树
public static boolean isBalanceTree(TreeNode node){
if(maxDeepBlance(node) != -1){
return true;
}
return false;
}
public static int maxDeepBlance(TreeNode node){
if(node == null){
return 0;
}
int left = maxDeepBlance(node.left);
int right = maxDeepBlance(node.right);
if(left == -1 || right == -1 || Math.abs(left-right) > 1){
return -1;
}
return Math.max(left, right) + 1;
}
7、判断是否是完全二叉树
//7、是否是完全二叉树
public static boolean isCompleteTree(TreeNode node){
//找到一非满结点后flag=1,如果发现一个非满结点,接下来的结点不能有孩子结点了
//如果有孩子结点,就说明不是完全二叉树,完全二叉树是从左边依次开始排列的
if(node == null){
return false;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(node);
boolean result = true;
boolean flag = false;
while(!queue.isEmpty()){
TreeNode current = queue.remove();
if(flag){
if(current.left != null || current.right != null){
//如果该结点有孩子结点,是不对的
result = false;
break;
}
}else{
if(current.left != null && current.right != null){
queue.add(current.left);
queue.add(current.right);
}else if(current.left != null && current.right == null){
queue.add(current.left);
flag = true;
}else if(current.left == null && current.right != null){
result = false;
break;
}else{
flag = true;
}
}
}
return result;
}
8、两个二叉树是否完全相同
//8、两个二叉树是否完全相同
public static boolean isSameTreeNode(TreeNode node1, TreeNode node2){
if(node1 == null && node2 == null){
return true;
}else if(node1 == null || node2 == null){
return false;
}
if(node1.val != node2.val){
return false;
}
boolean left = isSameTreeNode(node1.left, node2.left);
boolean right = isSameTreeNode(node1.right, node2.right);
return left && right;
}
9、两个二叉树是否互为镜像
//9、两个二叉树是否互为镜像
public static boolean isMirror(TreeNode node1, TreeNode node2){
if(node1 == null && node2 == null){
return true;
}else if(node1 == null || node2 == null){
return false;
}
if(node1.val != node2.val){
return false;
}
boolean left = isMirror(node1.left, node2.right);
boolean right = isMirror(node1.right, node2.left);
return left && right;
}
10、将二叉树进行反转
//10、翻转二叉树或者叫镜像二叉树
public static TreeNode MirrorTree(TreeNode node){
if(node == null){
return null;
}
TreeNode left = MirrorTree(node.left);
TreeNode right = MirrorTree(node.right);
node.left = right;
node.right = left;
return node;
}
11、求两个二叉树的最低公共祖先结点
//11、求两个二叉树的最低公共祖先结点
public static TreeNode getLastCommonParent(TreeNode root, TreeNode node1, TreeNode node2){
if (root == node1 || root == node2) {
return root;
}
int min = Math.min(node1.val, node2.val);
int max = Math.max(node1.val, node2.val);
//如果root结点的值大于最大值,就向左搜索
if (root.val > max) {
return getLastCommonParent(root.left, node1, node2);
} else if (root.val < min) {
//如果最小结点的值小于root结点,就向右搜索
return getLastCommonParent(root.right, node1, node2);
}
//如果root的值处在这两个中间,就返回
return root;
}
当二叉树不是二叉搜素数的时候,按照如下方法进行遍历
public static Node lowestAncestor(Node head, Node o1, Node o2) {
if (head == null || head == o1 || head == o2) {
return head;
}
Node left = lowestAncestor(head.left, o1, o2);
Node right = lowestAncestor(head.right, o1, o2);
if (left != null && right != null) {
return head;
}
return left != null ? left : right;
}
这是按照后序遍历的方式,如果左右都不为空就放回结果了,如果左右都为空或者有一个不为空就直接返回这个结点
12、二叉树的前序遍历迭代方式
//12、二叉树的前序遍历
public static ArrayList<Integer> preOrder(TreeNode root){
Stack<TreeNode> stack = new Stack<TreeNode>();
ArrayList<Integer> list = new ArrayList<Integer>();
if(root == null){
return null;
}
stack.push(root);
while(!stack.empty()){
TreeNode node = stack.pop();
list.add(node.val);
if(root.right!=null){
stack.push(root.right);
}
if(root.left != null){
stack.push(root.left);
}
}
return list;
}
13、二叉树的前序遍历递归方式
//13、二叉树前序遍历的递归方式
public static ArrayList<Integer> preOrderReverse(TreeNode root){
ArrayList<Integer> result = new ArrayList<Integer>();
preOrder2(root,result);
return result;
}
public static void preOrder2(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
result.add(root.val);
preOrder2(root.left,result);
preOrder2(root.right,result);
}
14、二叉树的中序遍历迭代方式
//14、二叉树中序遍历普通方式
public static ArrayList<Integer> inOrder(TreeNode root){
ArrayList<Integer> list = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode current = root;
while(current != null || !stack.empty()){
while(current != null){
stack.add(current);
current = current.left;
}
current = stack.pop();
list.add(current.val);
current = current.right;
}
return list;
}
15、二叉树是中序遍历递归方式
//15、二叉树前中遍历的递归方式
public static ArrayList<Integer> inOrderReverse(TreeNode root){
ArrayList<Integer> result = new ArrayList<Integer>();
inOrder2(root,result);
return result;
}
public static void inOrder2(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
inOrder2(root.left,result);
result.add(root.val);
inOrder2(root.right,result);
}
16、二叉树的后序遍历迭代方式
//16、二叉树后序遍历普通
public static ArrayList<Integer> postOrder(TreeNode root){
ArrayList<Integer> res = new ArrayList<Integer>();
if(root == null){
return null;
}
Stack<TreeNode> s = new Stack<TreeNode>();
Stack<TreeNode> out = new Stack<TreeNode>();
s.push(root);
while(!s.isEmpty()){
TreeNode cur = s.pop();
out.push(cur);
//前序的时候这里是先入的右结点,这里变了一下顺序
if (cur.left != null) {
s.push(cur.left);
}
if (cur.right != null) {
s.push(cur.right);
}
}
//进行一个逆序就可以了
while(!out.isEmpty()) {
res.add(out.pop().val);
}
return res;
}
17、二叉树的后序遍历递归方式
//17、二叉树后序遍历递归
public static ArrayList<Integer> postOrderReverse(TreeNode root){
ArrayList<Integer> result = new ArrayList<Integer>();
postOrder2(root,result);
return result;
}
public static void postOrder2(TreeNode root,ArrayList<Integer> result){
if(root == null){
return;
}
postOrder2(root.left,result);
postOrder2(root.right,result);
result.add(root.val);
}
18、根据前序和中序来构造二叉树
//18、二叉树前序和中序构造二叉树
public TreeNode buildTreeNode(int[] preorder, int[] inorder){
if(preorder.length != inorder.length){
return null;
}
return myBuildTree(inorder,0,inorder.length-1,preorder,0,preorder.length-1);
}
public TreeNode myBuildTree(int[] inorder,int instart,int inend,
int[] preorder,int prestart,int preend){
if(instart > inend){
return null;
}
TreeNode root = new TreeNode(preorder[prestart]);
int position = findPosition(inorder,instart,inend,preorder[prestart]);
root.left = myBuildTree(inorder,instart,position-1,preorder,prestart+1,prestart+position-instart);
root.right = myBuildTree(inorder,position+1,inend,preorder,position-inend+preend+1,preend);
return root;
}
public int findPosition(int[] arr, int start, int end, int key){
int i;
for(i = start; i <= end; i++){
if(arr[i] == key){
return i;
}
}
return -1;
}
19、二叉搜索树中合适位置插入结点
//19、在二叉树中插入结点
public TreeNode insertNode(TreeNode root,TreeNode node){
//这个树的结构是 左 < 中 < 右 的结构
if(root == node){
return node;
}
//临时结点
TreeNode tmp = new TreeNode();
tmp = root;
TreeNode last = null;
//找到合适的位置
while(tmp != null){
last = tmp;
if(tmp.val > node.val){
tmp = tmp.left;
}else{
tmp = tmp.right;
}
}
//将结点插入到里面
if(last != null){
if(last.val > node.val){
last.left = node;
}else{
last.right = node;
}
}
return root;
}
20、打印二叉树中路径和等于给定值的所有路径
//20、打印出二叉树中结点值等于和的所有路径
public void findPath(TreeNode root, int i){
if(root == null){
return;
}
Stack<Integer> stack = new Stack<Integer>();
int currentSum = 0;
findPath(root, i, stack, currentSum);
}
public void findPath(TreeNode root, int i, Stack<Integer> stack,int currentSum){
currentSum = currentSum + root.val;
stack.push(root.val);
//如果两边都为空就进行判断
if(root.left == null && root.right == null){
if(currentSum == i){
for(int path : stack){
System.out.println(path);
}
}
}
//如果左边不为空
if(root.left != null){
findPath(root.left, i, stack, currentSum);
}
//如果右边不为空
if(root.right != null){
findPath(root.right, i, stack, currentSum);
}
}
21、二叉树的搜索区间,范围爱k1-k2内的结点
//21、二叉树的搜索区间
public static ArrayList<Integer> result;
public static ArrayList<Integer> searchRange(TreeNode root,int k1,int k2){
result = new ArrayList<Integer>();
searchHelper(root,k1,k2);
return result;
}
public static void searchHelper(TreeNode root, int k1, int k2) {
if(root == null){
return ;
}
if(root.val > k1){
searchHelper(root.left, k1, k2);
}
if(root.val >= k1 && root.val <= k2){
result.add(root.val);
}
if(root.val < k2){
searchHelper(root.right, k1, k2);
}
}
22、二叉树的层次遍历
//22、二叉树的层次遍历
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root){
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if(root == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
ArrayList<Integer> level = new ArrayList<Integer>();
for(int i = 0; i < size; i++){
TreeNode current = queue.poll();
level.add(current.val);
if(current.left != null){
queue.offer(current.left);
}
if(current.right != null){
queue.offer(current.right);
}
}
result.add(level);
}
return result;
}
23、二叉树是否为二叉查找树
//23、判读二叉树是否是二叉查找数
public int lastVal = Integer.MAX_VALUE;
public boolean firstNode = true;
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
if(!isBalanceTree(root.left)){
return false;
}
if(!firstNode && lastVal >= root.val){
return false;
}
firstNode = false;
lastVal = root.val;
if(!isBalanceTree(root.right)){
return false;
}
return true;
}
尊重作者 尊重原创 参考文章:
http://www.jianshu.com/p/0190985635eb
http://blog.csdn.net/yangcs2009/article/details/40146967