算法:二叉树理论知识
来源:互联网 发布:windows nt 6.1.7601 编辑:程序博客网 时间:2024/06/07 22:53
一、树结构的基础术语
树的结点:包含一个数据元素及若干指向其子树的分支。
结点的度(Degree):结点拥有的子树数。eg:上图中,A的度为3,C的度为1,F的度为0。
叶子结点(Leaf)或终端结点:度为0的结点。eg:上图中,K,L,F,G,H,I,J都是树的叶子结点。
分支结点或非终端结点:度不为0的结点。
树的度:树内各结点的度的最大值。eg:上图中,树的度为3。
结点的孩子(Child):结点的子树的根称为该结点的孩子。相应的该节点称为孩子的双亲(Parent)。
eg:上图中,D为A的子树的根,则D是A的孩子,而A是D的双亲。
兄弟结点(Sibling):同一个双亲的孩子之间互称为兄弟。
eg:结点B,C,D都有同一个双亲A,所以B,C,D互称为兄弟结点。
结点的祖先:从根到该结点所经分支上的所有结点。eg:M的祖先为A,D,H。
子孙结点:以某结点为根的子树中的任一结点都称为该结点的子孙。eg:B的子孙为E,K,L 和 F。
结点的层次(Level):从根开始定义,根为第一层,根的孩子为第二层。
eg:上图中,树总共有4层:A为第一层;B,C,D为第二层,依次递推。
树的深度(Depth)或高度:树中结点的最大层次。eg:上图中,树的深度为4。
有序树:如果将树中的各子树看成从左至右是有次序的(即不能互换),则称该树为有序树;
否则为无序树。
二、二叉树定义
二叉树(Binary Tree):是一种特殊的树型结构,它的特点:
1.每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点);
2.二叉树的子树有左右之分,其次序不能任意颠倒(即二叉树是有序树)。
满二叉树:深度为k且有2^k-1个结点的二叉树称为满二叉树。
完全二叉树:对满二叉树的结点进行连续标号,约定编号从根结点起,自上而下,自左至右,由此引出完全二叉树定义。深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1到n的结点一一对应时,称之为完全二叉树。
二叉树性质
二叉树具有下列重要特性:
性质1:在二叉树的第i层上至多有2^(i-1)个结点,其中i >= 1。
性质2:深度为k的二叉树至多有2^k-1个结点,其中k >= 1。
性质3:对于任意一棵二叉树T,如果其叶子结点个数为n0,度为2的结点个数为n2,则n0=n2+1。
证明:设n1为二叉树度为1的结点个数。因为二叉树中所有结点的度均小于或等于2。所以其结点总数n为:
n=n0 + n1 +n2 (6-1)
再看二叉树中的分支数。除了根节点外,其余结点都有一个分支进入,设B是分支总数,则n=B+1。由于这些分支是由度为1或2的结点射出的,所以又有B=n1+n2。于是得:
n=n1 + 2 * n2 + 1 (6-2)
由式 (6-1)和(6-2)得:
n0 = n2 + 1
性质4:具有n个结点的完全二叉树深度为log2n(向下取整) +1。
二叉树构建(java实现)
代码中int[] levelorder2
是二叉树层次遍历得到的数组,0代表结点为null。
int[] levelorder2 = {0,1,2,3,4,5,6,7,0,0,0,0,0,0,0,0}; //特别注意:数组index=0的位置不使用TreeNode root2 = TreeNodeUtil.makeBinaryTreeByArray(levelorder2, 1);
public static TreeNode makeBinaryTreeByArray(int[] a, int index){ if(index < a.length){ int value = a[index]; if(value != 0){ TreeNode node = new TreeNode(value); //a[index]=0; node.left = makeBinaryTreeByArray(a, index*2); node.right = makeBinaryTreeByArray(a, index*2+1); return node; } } return null; }
二叉树遍历(java实现)
先序遍历(深度优先遍历DFS)、中序遍历、后序遍历,广度优先遍历BFS
1.先序遍历
/** * 先序遍历二叉树:递归实现 * @param root */ public static void preTraverse(TreeNode root){ if(root != null){ System.out.print(root.val + " "); preTraverse(root.left); preTraverse(root.right); } }
1.1先序遍历—非递归实现(使用栈数据结构)
/** * 先序遍历:非递归实现(DFS深度优先遍历) * * @param root */ public static void perTraverseNoRecursion(TreeNode root){ Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while(!stack.isEmpty()){ TreeNode node = stack.pop(); System.out.print(node.val + " "); if (node.right != null) {//先右后左,右节点先入栈 stack.push(node.right); } if (node.left != null) { stack.push(node.left); } }//end while }//end method
2.中序遍历
/** * 中序遍历二叉树:递归实现 * @param root */ public static void inTraverse(TreeNode root){ if(root != null){ inTraverse(root.left); System.out.print(root.val + " "); inTraverse(root.right); } }
3.后序遍历
/** * 后序遍历二叉树:递归实现 * @param root */ public static void postTraverse(TreeNode root){ if(root != null){ postTraverse(root.left); postTraverse(root.right); System.out.print(root.val + " "); } }
4.BFS遍历
/** * 广度优先遍历BFS:非递归实现 * @param root * * 说明:队列是先入先出的数据结构(FIFO) very nice! */ public static void levelTraverse(TreeNode root) { Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.offer(root);// 从根节点入队列 while (!queue.isEmpty()) {// 在队列为空前反复迭代 TreeNode TreeNode = queue.poll();// 取出队列首节点 System.out.print(TreeNode.val + " "); if (TreeNode.left != null) queue.offer(TreeNode.left);// 左孩子入列 if (TreeNode.right != null) queue.offer(TreeNode.right);// 右孩子入列 } }
三、二叉搜索树
1. 二叉搜索树定义
二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
1.若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2.若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
3.任意节点的左、右子树也分别为二叉查找树;
4.没有键值相等的节点。
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构
2. 平衡二叉搜索树
平衡二叉搜索树(Balanced Binary Tree)是一种结构平衡的二叉搜索树,即叶节点深度差不超过1,它能在O(log n)内完成插入、查找和删除操作。
3. 使用排序数组,构建平衡二叉搜索树
/** * 通过一个升序数组,构建平衡二叉搜索树(Binary Search Tree) * * @param nums * @return */ public static TreeNode sortedArrayToBST(int[] num) { if (num == null || num.length == 0) { return null; } return helper(num, 0, num.length - 1); } public static TreeNode helper(int[] num, int low, int high) { if (low > high) { // Done 递归出口 return null; } int mid = (low + high) / 2; TreeNode node = new TreeNode(num[mid]); node.left = helper(num, low, mid - 1); //左半部分递归 node.right = helper(num, mid + 1, high); //右半部分递归 return node; }
4. 平衡二叉搜索树,插入结点
/** * 二叉搜索树(Binary Search Tree):插入元素 * @param root * @param element * @return */ public static boolean insertBST(TreeNode root, int element){ if(root == null){ //空树情况 root = new TreeNode(); root.val = element; root.left = root.right = null; }else if(element == root.val){ //值相等情况 return false; }else if(element < root.val){ insertBST(root.left, element); }else{ insertBST(root.right, element); } return true; }//end method
- 算法:二叉树理论知识
- 理论知识
- 理论知识
- 理论知识
- DH算法证明及相应的理论知识
- RSA算法及其相应的理论知识
- 线索二叉树算法
- 数据结构-二叉树算法
- 【算法】二叉树
- 二叉树相关算法
- 二叉树相关算法
- 二叉树深度算法
- 二叉树算法
- 二叉树算法
- 二叉树相关算法
- 二叉树算法
- 线索二叉树算法
- 二叉树遍历算法
- Knn
- [k8s]yaml常用
- AutoNest_v1.6_for_AutoCAD.rar
- I2C总线之(三)---以C语言理解IIC
- Map遍历的方法
- 算法:二叉树理论知识
- 关于node的学习
- Hibernate学习---基本介绍+作用+配置
- [!] The version of CocoaPods used to generate the lockfile (1.3.1) is higher than the version of the
- 以下七种人,绝对不要借钱给TA
- 运用集合实现用户的注册和登录
- POJ3009---冰壶游戏(深搜剪枝+回溯)
- 立即执行函数表达式
- 杂技