线索二叉树(中序、先序和后序及遍历)

2023-11-16

链式存储

线索二叉树是二叉树的一类,在看线索二叉树之前我们先看一下二叉树的链式存储。
链式存储
一个二叉树的存储例子(后面用到的二叉树都是这棵):
链式存储2
代码是这样的:

public class BinaryTreeNode<T>{
	private T data;							//数据域
	private BinaryTreeNode<T> leftChild;	//左指针域
	private BinaryTreeNode<T> rightChild;	//右指针域
}

上图中的“#”号空指针,会浪费一部分空间。对于二叉树的一个节点,查找其左右子女是方便的,其前驱和后继只有在遍历中得到。为了容易找到前驱和后继就会利用这部分空间保存按照某一遍历遍历出来的前驱或后继节点。

线索二叉树

我们在做遍历的时候,比如对上图中的树做中序遍历时,得到DBGEAFC字符序列,遍历过后,我们就可以知道节点E的前驱是G后继是A,节点F的前驱是A后继是C。也就是说遍历过后,我们可以很清楚的知道任意一个节点的的前驱和后继。

  • 中序线索二叉树:按中序遍历。
  • 先序线索二叉树:按先序遍历。
  • 后序线索二叉树:按后序遍历。

这是建立在遍历过的基础上,在二叉链表上,我们只能知道每个节点指向其左右孩子节点的地址,而不知道每个节点的前驱和后继,要想知道,必须遍历一次,以后每次需要知道时,都必须先遍历一次,那得多浪费时间。我们可以考虑在创建时就记住这些前驱和后继。这个时候我们就可以考虑利用那些空地址,存放指向节点在某种遍历次序下的前驱和后继节点的地址。这种指向前驱和后继的指针称为线索,所以叫线索二叉树。总结一下:

  • 若当前节点左指针域非空时,保留原指针不变;若左指针域为空时,添加该节点在相应遍历序列中前驱节点地址。
  • 若当前结点右指针域非空时,保留原指针不变;若右指针域为空时,添加该节点在相应遍历序列中后继节点地址。

这里要注意一下,我们怎么判断左/右指针域指向的是原指针还是前驱/后继节点?两个布尔变量。flase表示原指针(左/右子树),true表示前驱/后继节点。
在这里插入图片描述

public class CluesBinaryTreeNode<T>{
	private T data;								//数据域
	private CluesBinaryTreeNode<T> leftChild;	//左指针域
	private CluesBinaryTreeNode<T> rightChild;	//右指针域
	private boolean leftIsPriorLink;			//是否是前驱节点
	private boolean rightIsNextLink;			//是否是后继节点
}

中序线索二叉树

一个中序线索二叉树的例子(遍历是DBGEAFC):
中序线索二叉树例子

中序线索化实现

线索化:中序线索二叉树,就按照中序遍历,遍历的过程中在当前节点的左或右空指针域中添加前驱或后继节点。为了保留遍历过程中访问节点的前驱与后继关系,需要设置一个前一节点变量priorNode始终指向刚访问过的节点。

  • 如果当前节点cur.leftChild == null(左子节点为空),则cur.leftIsPriorLink = true;cur.leftChild = priorNode;(左指针域指向前驱节点,修改leftIsPriorLink为线索模式即true)。
  • 如果前一节点priorNode.rightChild == null(右子结点为空),则priorNode.rightIsNextLink = true;priorNode.rightChild = cur;(右指针域指向后继节点,修改rightIsNextLink为线索模式即true)。
    public void inorderClues(TreeNode<T> tree){
        if (tree == null){
            return;
        }

        inorderClues(tree.leftChild);           //左节点

        if (tree.leftChild == null){            //根节点
            tree.leftIsPriorLink = true;
            tree.leftChild = priorNode;
        }
        if (priorNode != null && priorNode.rightChild == null){
            priorNode.rightIsNextLink = true;
            priorNode.rightChild = tree;
        }

        priorNode = tree;
        inorderClues(tree.rightChild);          //右节点
    }

注:priorNode是类的成员变量,完整代码在后面。

实现的代码过程

省略了一些无关紧要的代码
实现的过程

中序线索二叉树的遍历

分两步,①获取中序遍历的首节点。②获取中序线索化二叉树中当前节点的后继节点。只要完成这两步就可以遍历中序线索化二叉树。

  • 获取中序遍历的首节点:从根节点开始沿着左指针不断向左下搜索,直到找到最左的节点。最左的节点指该节点左指针为空。
  • 获取中序线索化二叉树中当前节点的后继节点:有两种情况
    ①当前节点存在右子树:则从该右子树根节点开始不断向左下搜索,找到找到最左的节点。该节点即当前节点的后继。
    ②当前节点不存在右子树:则其后继节点即为其右指针域中后继线索所指节点。
    下面是步骤图,可以边看代码边看此图:
    中序线索二叉树遍历过程
遍历代码
public void inorderTraversal(TreeNode<T> tree){
        if (tree == null){return;}

        TreeNode<T> node = tree.leftChild;

        if (node == null){ return;}

        while (node.leftChild != null && !node.leftIsPriorLink){        //循环到最左节点
            node = node.leftChild;
        }

        while (node != null){
            System.out.print(node.data);
            if (node.rightChild != null && !node.rightIsNextLink){      //当前节点存在右子树
                node = node.rightChild;
                while (node.leftChild != null && !node.leftIsPriorLink){    //循环到最左节点
                    node = node.leftChild;
                }
            }else{
                node = node.rightChild;                                 //后继线索所指节点
            }
        }
    }

中序线索二叉树可运行代码

public class CluesBinaryTreeNode<T>{

    private TreeNode priorNode;

    private class TreeNode<T>{
        private T data;								//数据域
        private TreeNode<T> leftChild;				//左指针域
        private TreeNode<T> rightChild;				//右指针域
        private boolean leftIsPriorLink;			//是否是前驱节点
        private boolean rightIsNextLink;			//是否是后继节点

        public TreeNode(){}
        public TreeNode(T data){this.data=data;}

    }

    /**
     * 递归,中序创建线索二叉树
     * @param tree 树根
     */
    public void inorderClues(TreeNode<T> tree){
        if (tree == null){
            return;
        }

        inorderClues(tree.leftChild);           //左节点

        if (tree.leftChild == null){            //根节点
            tree.leftIsPriorLink = true;
            tree.leftChild = priorNode;
        }
        if (priorNode != null && priorNode.rightChild == null){
            priorNode.rightIsNextLink = true;
            priorNode.rightChild = tree;
        }

        priorNode = tree;
        inorderClues(tree.rightChild);          //右节点
    }

    /**
     * 中序线索化二叉树的遍历
     * @param tree
     */
    public void inorderTraversal(TreeNode<T> tree){
        if (tree == null){return;}

        TreeNode<T> node = tree.leftChild;

        if (node == null){ return;}

        while (node.leftChild != null && !node.leftIsPriorLink){        //循环到最左节点
            node = node.leftChild;
        }

        while (node != null){
            System.out.print(node.data);
            if (node.rightChild != null && !node.rightIsNextLink){      //当前节点存在右子树
                node = node.rightChild;
                while (node.leftChild != null && !node.leftIsPriorLink){    //循环到最左节点
                    node = node.leftChild;
                }
            }else{
                node = node.rightChild;                                 //后继线索所指节点
            }
        }
    }

    public static void main(String[] args) {
       CluesBinaryTreeNode<String> cluesTree = new CluesBinaryTreeNode<String>();
        CluesBinaryTreeNode.TreeNode rootNode = cluesTree.new TreeNode<>();

        rootNode.data = "A";
        
        rootNode.leftChild=cluesTree.new TreeNode<>("B");
        rootNode.rightChild=cluesTree.new TreeNode<>("C");
        
        rootNode.leftChild.leftChild=cluesTree.new TreeNode<>("D");
        rootNode.rightChild.leftChild=cluesTree.new TreeNode<>("F");
        rootNode.leftChild.rightChild=cluesTree.new TreeNode<>("E");
        
        rootNode.leftChild.rightChild.leftChild=cluesTree.new TreeNode<>("G");

       	cluesTree.inorderClues(rootNode);                           //中序线索化二叉树
        cluesTree.inorderTraversal(rootNode);                       //遍历中序线索化二叉树
    }
}

运行结果(这棵二叉树就是上面图中的二叉树):运行结果

先序线索二叉树

一个先序线索二叉树的例子(遍历是ABDEGCF):
先序线索二叉树

先序线索化实现

线索化:和中序线索化实现一样(把中序遍历改为先序遍历)。
因为遍历的顺序不一样,所以需要注意的先序和中序有个地方不一样,先序我们要判断是否是左子树/右子树在进行递归,不然会出现死递归。

  • 判断是否是左子树(即不能是前驱节点):先序的遍历顺序是"根左右",在对"左"节点进行遍历的时候当"左"节点没有左子树时,“左"节点的前驱节点就设置为"根"节点,此时在遍历”左“节点的"左"节点,就又会遍历"根节点”,就会形成死循环。如上图中的D.leftChild是前驱节点不是左子树,如果不判断就会在像B和D节点这种节点上死循环根左根左根左…,BDBDBD…。
  • 判断是否是右子树(即不能是后驱节点):在previousClues(E)中遍历E.leftChild(G节点)节点时即previousClues(G),此时priorNode=E不为空有priorNode.rightChild=G(E.rightChild=G),priorNode=G。然后回到previousClues(E)方法中如果不判断就会进入previousClues(G)中,此时priorNode=G不为空有priorNode.rightChild=G(G.rightChild=G)。就会形成死循环GGGGG…。
 public void previousClues(TreeNode<T> tree){
        if (tree == null){
            return;
        }
        if (tree.leftChild == null){            //根节点
            tree.leftIsPriorLink = true;
            tree.leftChild = priorNode;
        }
        if (priorNode != null && priorNode.rightChild == null){
            priorNode.rightIsNextLink = true;
            priorNode.rightChild = tree;
        }
        priorNode = tree;

        if (!tree.leftIsPriorLink){             //判断是否有左子树
            previousClues(tree.leftChild);
        }
        if (!tree.rightIsNextLink){             //判断是否有右子树
            previousClues(tree.rightChild);
        }
    }

先序线索二叉树的遍历

先序线索二叉树的遍历就简单了,让我们看一下下面这个先序线索二叉树的遍历。ABDEGCF。从根节点一直遍历到最左节点(根节点没有左节点的话,根节点就是"最左节点"),最左节点的右节点(右子树或后继节点)就是下一个要遍历的节点,一直重复这个步骤,先序线索二叉树的遍历就完成了。
先序遍历过程

遍历代码
 public void previousTraversal(TreeNode<T> tree){
        while (tree != null){
            System.out.print(tree.data);
            if (tree.leftChild != null && !tree.leftIsPriorLink){   //左子树
                tree = tree.leftChild;
            }else {
                tree = tree.rightChild;                             //右子树或者后继节点
            }
        }
    }

先序线索二叉树可运行代码

/**
 * 先序线索二叉树
 * @param <T>
 */
public class CluesBinaryTreeNode<T>{

    private TreeNode priorNode;

    private class TreeNode<T>{
        private T data;								//数据域
        private TreeNode<T> leftChild;				//左指针域
        private TreeNode<T> rightChild;				//右指针域
        private boolean leftIsPriorLink;			//是否是前驱节点
        private boolean rightIsNextLink;			//是否是后继节点

        public TreeNode(){}
        public TreeNode(T data){this.data=data;}

    }

    /**
     * 递归,先序创建线索二叉树
     * @param tree 树根
     */
    public void previousClues(TreeNode<T> tree){
        if (tree == null){
            return;
        }
        if (tree.leftChild == null){            //根节点
            tree.leftIsPriorLink = true;
            tree.leftChild = priorNode;
        }
        if (priorNode != null && priorNode.rightChild == null){
            priorNode.rightIsNextLink = true;
            priorNode.rightChild = tree;
        }
        priorNode = tree;

        if (!tree.leftIsPriorLink){             //判断是否有左子树
            previousClues(tree.leftChild);
        }
        if (!tree.rightIsNextLink){             //判断是否有右子树
            previousClues(tree.rightChild);
        }
    }

    /**
     * 先序线索化二叉树的遍历
     * @param tree
     */
    public void previousTraversal(TreeNode<T> tree){
        while (tree != null){
            System.out.print(tree.data);
            if (tree.leftChild != null && !tree.leftIsPriorLink){   //左子树
                tree = tree.leftChild;
            }else {
                tree = tree.rightChild;                             //右子树或者后继节点
            }
        }
    }

    public static void main(String[] args) {
        CluesBinaryTreeNode<String> cluesTree = new CluesBinaryTreeNode<String>();
        CluesBinaryTreeNode.TreeNode rootNode = cluesTree.new TreeNode<>();

        rootNode.data = "A";

        rootNode.leftChild=cluesTree.new TreeNode<>("B");
        rootNode.rightChild=cluesTree.new TreeNode<>("C");

        rootNode.leftChild.leftChild=cluesTree.new TreeNode<>("D");
        rootNode.rightChild.leftChild=cluesTree.new TreeNode<>("F");
        rootNode.leftChild.rightChild=cluesTree.new TreeNode<>("E");

        rootNode.leftChild.rightChild.leftChild=cluesTree.new TreeNode<>("G");

        cluesTree.previousClues(rootNode);                              //中序线索化二叉树
        cluesTree.previousTraversal(rootNode);                       //遍历中序线索化二叉树
    }
}

运行结果(这棵二叉树就是上面图中的二叉树):运行结果

后序线索二叉树

后序的遍历顺序是:左右根,根是最后遍历的,我们遍历孩子节点要回到根节点只能在树节点中多加一个指针指向父结点。

public class CluesBinaryTreeNode<T>{
	private T data;								//数据域
	private CluesBinaryTreeNode<T> leftChild;	//左指针域
	private CluesBinaryTreeNode<T> rightChild;	//右指针域
	private CluesBinaryTreeNode<T> parent;		//父指针域
	private boolean leftIsPriorLink;			//是否是前驱节点
	private boolean rightIsNextLink;			//是否是后继节点
}

一个后序线索二叉树例子(遍历是DGEBFCA,父指针域就不表示出来了):
后序线索二叉树例子

后序线索化实现

线索化:和中序线索化实现一样(把中序遍历改为后序遍历)。

public void afterClues(TreeNode<T> tree){
        if (tree == null){
            return;
        }

        afterClues(tree.leftChild);
        afterClues(tree.rightChild);

        if (tree.leftChild == null){            //根节点
            tree.leftIsPriorLink = true;
            tree.leftChild = priorNode;
        }
        if (priorNode != null && priorNode.rightChild == null){
            priorNode.rightIsNextLink = true;
            priorNode.rightChild = tree;
        }
        priorNode = tree;
    }

后序线索二叉树的遍历

  • 遍历的起点:根节点左子树最左边的节点。该节点不一定是第一个打印数据的节点,该节点可能存在右子树,存在右子树要遍历右子树。
  • 后继:一直遍历该节点的后继节点,没有后继节点就判断是不是根节点(根节点没有右子树时就会出现这种情况)。如果不是根节点,那就找到节点的父亲,一直到找到根节点,继续判断根节点是不是存在右子树。
    下面是步骤图,可以边看代码边看此图:
    后序线索二叉树的遍历
遍历代码
public void afterTraversal(TreeNode<T> tree){
        if (tree == null){
            return;
        }

        TreeNode<T> node = tree;

        TreeNode<T> prevNode = null;

        while (node != null){
            while (node.leftChild != null && !node.leftIsPriorLink){        //循环到最左节点
                node = node.leftChild;
            }

            while (node != null && node.rightIsNextLink){                   //循环后继节点
                System.out.print(node.data);
                prevNode = node;
                node = node.rightChild;
            }

            if (node == tree){
                System.out.println(node.data);
                return;
            }

            while (node != null && node.rightChild == prevNode){    //判断到根节点
                System.out.print(node.data);
                prevNode = node;
                node = node.parent;                     //回到父节点
            }

            if (node !=null && !node.rightIsNextLink){  //
                node = node.rightChild;
            }
        }
    }

后序线索二叉树可运行代码

/**
 * 后序线索二叉树
 * @param <T>
 */
public class CluesBinaryTreeNode<T>{

    private TreeNode priorNode;

    private class TreeNode<T>{
        private T data;								//数据域
        private TreeNode<T> leftChild;				//左指针域
        private TreeNode<T> rightChild;				//右指针域
        private TreeNode<T> parent;     			//父指针域
        private boolean leftIsPriorLink;			//是否是前驱节点
        private boolean rightIsNextLink;			//是否是后继节点

        public TreeNode(){}
        public TreeNode(T data){this.data=data;}

    }

    /**
     * 递归,后序创建线索二叉树
     * @param tree 树根
     */
    public void afterClues(TreeNode<T> tree){
        if (tree == null){
            return;
        }

        afterClues(tree.leftChild);           //左节点
        afterClues(tree.rightChild);          //右节点

        if (tree.leftChild == null){            //根节点
            tree.leftIsPriorLink = true;
            tree.leftChild = priorNode;
        }
        if (priorNode != null && priorNode.rightChild == null){
            priorNode.rightIsNextLink = true;
            priorNode.rightChild = tree;
        }

        priorNode = tree;
    }

    /**
     * 后序线索化二叉树的遍历
     * @param tree
     */
    public void afterTraversal(TreeNode<T> tree){
        if (tree == null){
            return;
        }

        TreeNode<T> node = tree;

        TreeNode<T> prevNode = null;

        while (node != null){
            while (node.leftChild != null && !node.leftIsPriorLink){        //循环到最左节点
                node = node.leftChild;
            }

            while (node != null && node.rightIsNextLink){                   //循环后继节点
                System.out.print(node.data);
                prevNode = node;
                node = node.rightChild;
            }

            if (node == tree){
                System.out.println(node.data);
                return;
            }

            while (node != null && node.rightChild == prevNode){    //判断到根节点
                System.out.print(node.data);
                prevNode = node;
                node = node.parent;                     //回到父节点
            }

            if (node !=null && !node.rightIsNextLink){  //
                node = node.rightChild;
            }
        }
    }

    public static void main(String[] args) {
        CluesBinaryTreeNode<String> cluesTree = new CluesBinaryTreeNode<String>();
        CluesBinaryTreeNode.TreeNode rootNode = cluesTree.new TreeNode<>();

        rootNode.data = "A";

        rootNode.leftChild=cluesTree.new TreeNode<>("B");
        rootNode.leftChild.parent=rootNode;
        rootNode.rightChild=cluesTree.new TreeNode<>("C");
        rootNode.rightChild.parent=rootNode;

        rootNode.leftChild.leftChild=cluesTree.new TreeNode<>("D");
        rootNode.leftChild.leftChild.parent=rootNode.leftChild;

        rootNode.rightChild.leftChild=cluesTree.new TreeNode<>("F");
        rootNode.rightChild.leftChild.parent=rootNode.rightChild;
        rootNode.leftChild.rightChild=cluesTree.new TreeNode<>("E");
        rootNode.leftChild.rightChild.parent=rootNode.leftChild;
//
        rootNode.leftChild.rightChild.leftChild=cluesTree.new TreeNode<>("G");
        rootNode.leftChild.rightChild.leftChild.parent=rootNode.leftChild.rightChild;


        cluesTree.afterClues(rootNode);                              //后序线索化二叉树
        cluesTree.afterTraversal(rootNode);                       //遍历后序线索化二叉树
    }
}

运行结果(这棵二叉树就是上面图中的二叉树):
运行结果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线索二叉树(中序、先序和后序及遍历) 的相关文章

  • Java - 因内存不足错误而关闭

    关于如何最好地处理这个问题 我听到了非常矛盾的事情 并且陷入了以下困境 OOME 会导致一个线程崩溃 但不会导致整个应用程序崩溃 我需要关闭整个应用程序 但不能 因为线程没有剩余内存 我一直认为最佳实践是让它们离开 这样 JVM 就会死掉
  • 如何使用Spring WebClient进行同步调用?

    Spring Framework in 休息模板 https docs spring io spring framework docs current javadoc api org springframework web client R
  • Guice 忽略注入构造函数参数上的 @Nullable

    我正在使用 Guice v 3 0 并且有一个值被注入到构造函数中 该值可以为 null 因此我在构造函数中使用 Nullable 来自 javax annotations 注释了该参数 public MyClass Parameter1
  • Java 7 默认语言环境

    我刚刚安装了 jre7 我很惊讶地发现我的默认区域设置现在是 en US 对于jre6 它是de CH 与jre7有什么不同 默认区域设置不再是操作系统之一吗 顺便说一句 我使用的是Windows7 谢谢你的回答 编辑 我已经看到了语言环境
  • Oracle Java 教程 - 回答问题时可能出现错误

    我是 Java 新手 正在阅读 Oracle 教程 每个部分之后都有问题和答案 我不明白一个答案中的一句话 见下面的粗体线 来源是https docs oracle com javase tutorial java javaOO QandE
  • 当路径的点超出视野时,Android Canvas 不会绘制路径

    我在绘制路径时遇到了 Android Canvas 的一些问题 我的情况是 我有一个相对布局工作 如地图视图 不使用 google api 或类似的东西 我必须在该视图上绘制一条路径 canvas drawPath polyPath bor
  • Base36 编码字符串?

    我一直在网上查找 但找不到解决此问题的方法 在 Python Ruby 或 Java 中 如何对以下字符串进行 Base 36 编码 nOrG9Eh0uyeilM8Nnu5pTywj3935kW 5 Ruby 以 36 为基数 s unpa
  • 文本在指定长度后分割,但不要使用 grails 打断单词

    我有一个长字符串 需要将其解析为长度不超过 50 个字符的字符串数组 对我来说 棘手的部分是确保正则表达式找到 50 个字符之前的最后一个空格 以便在字符串之间进行彻底的分隔 因为我不希望单词被切断 public List
  • Logback:SizeAndTimeBasedRollingPolicy 不遵守totalSizeCap

    我正在尝试以一种方式管理我的日志记录 一旦达到总累积大小限制或达到最大历史记录限制 我最旧的存档日志文件就会被删除 当使用SizeAndTimeBasedRollingPolicy在 Logback 1 1 7 中 滚动文件追加器将继续创建
  • tomcat 7.0.50 java websocket 实现给出 404 错误

    我正在尝试使用 Java Websocket API 1 0 JSR 356 中指定的带注释端点在 tomcat 7 0 50 上实现 websocket 以下是我如何对其进行编码的简要步骤 1 使用 ServerEndpoint注解编写w
  • 如何使用正则表达式验证 1-99 范围?

    我需要验证一些用户输入 以确保输入的数字在 1 99 范围内 含 这些必须是整数 Integer 值 允许前面加 0 但可选 有效值 1 01 10 99 09 无效值 0 007 100 10 5 010 到目前为止 我已经制定了以下正则
  • 如何通过注解用try-catch包装方法?

    如果应该在方法调用中忽略异常 则可以编写以下内容 public void addEntryIfPresent String key Dto dto try Map
  • 当 minifyEnabled 为 true 时 Android 应用程序崩溃

    我正在使用多模块应用程序 并且该应用程序崩溃时minifyEnabled true in the installed模块的build gradle 以下是从游戏控制台检索到的反混淆堆栈跟踪 FATAL EXCEPTION Controlle
  • 如何从日期中删除毫秒、秒、分钟和小时[重复]

    这个问题在这里已经有答案了 我遇到了一个问题 我想比较两个日期 然而 我只想比较年 月 日 这就是我能想到的 private Date trim Date date Calendar calendar Calendar getInstanc
  • 无法在 Java/Apache HttpClient 中处理带有垂直/管道栏的 url

    例如 如果我想处理这个网址 post new HttpPost http testurl com lists lprocess action LoadList 401814 1 Java Apache 不允许我这么做 因为它说竖线 是非法的
  • Java - 从 XML 文件读取注释

    我必须从 XML 文件中提取注释 我找不到使用 JDOM 或其他东西来让它们使用的方法 目前我使用 Regex 和 FileReader 但我不认为这是正确的方法 您可以使用 JDOM 之类的东西从 XML 文件中获取注释吗 或者它仅限于元
  • Hadoop NoSuchMethodError apache.commons.cli

    我在用着hadoop 2 7 2我用 IntelliJ 做了一个 MapReduce 工作 在我的工作中 我正在使用apache commons cli 1 3 1我把库放在罐子里 当我在 Hadoop 集群上使用 MapReduceJob
  • JMS 中的 MessageListener 和 Consumer 有什么区别?

    我是新来的JMS 据我了解Consumers能够从队列 主题中挑选消息 那么为什么你需要一个MessageListener因为Consumers会知道他们什么时候收到消息吗 这样的实际用途是什么MessageListener 编辑 来自Me
  • 检查应用程序是否在 Android Market 上可用

    给定 Android 应用程序 ID 包名称 如何以编程方式检查该应用程序是否在 Android Market 上可用 例如 com rovio angrybirds 可用 而 com random app ibuilt 不可用 我计划从
  • 基于 Spring Boot 的测试中的上下文层次结构

    我的 Spring Boot 应用程序是这样启动的 new SpringApplicationBuilder sources ParentCtxConfig class child ChildFirstCtxConfig class sib

随机推荐

  • 前端开发中常用的校验处理

    前端开发中常用的校验处理 1 手机号码校验 2 身份证正则校验 3 必须输入中文 必须输入英文 4 其它正则校验 1 手机号码校验 function checkPhone var phone document getElementById
  • C++类和对象(一):封装

    文章目录 0 类和对象 1 封装的意义 2 结构体struct和类class区别 3 成员属性设置为私有 4 封装特性的练习案例 点和圆的位置关系 0 类和对象 C 面向对象的三大特性 封装 继承 多态 C 中万物皆对象 对象包含属性 成员
  • 基于TensorFlow 实战案例:气温预测(附 Python 完整代码和数据集)

    文章目录 1 数据获取 2 数据可视化 3 特征处理 4 构建网络模型 1 网络搭建 2 优化器和损失函数 3 网络训练 4 网络模型结构 5 预测结果 5 结果展示 完整代码及数据 各位同学好 今天和大家分享一下TensorFlow2 0
  • Vue路由跳转时报错TypeError: Cannot read properties of undefined (reading ‘$createElement‘)

    错误的原因 单词写错 将component写成components
  • css 实现虚线效果的3种方式详解

    一 效果 首先可以看一下下图显示的实现效果 用三种方式实现了虚线效果 点击查看demo代码 二 实现 1 border 属性 查看 mdn 的 border 我们知道 border 可以用于设置一个或多个以下属性的值 border widt
  • 【Web server failed to start. Port 8080 was already in use】解决方案

    问题描述 你是否遇到过这个问题呢 无论是初学者 还是中高级开发者 你都会遇到这个问题 我们就来总结一下 Web server failed to start Port 8080 was already in use Description
  • 刷脸支付俨然形成风口抓住风口才能起飞

    刷脸支付项项目的热度越来越高 更多的支付巨头参与到其中来 最近各大银行联合发布了刷脸支付刷脸付 把刷脸支付的热度推到一个新的高度 刷脸支付这么火热 各大支付巨头纷纷投入巨额资金抢占市场 随着我国支付行业的发展 刷脸支付已然成为下一代支付方式
  • 恶劣天气 3D 目标检测数据集收集

    Summary of the Adverse Weather 3D Object Detection Dataset DENSE数据集 CADC数据集 Ithaca365数据集 DENSE数据集 论文地址 https arxiv org p
  • 设备树(dtb数据)匹配struct machine_desc结构体

    1 函数调用关系 start kernel setup arch setup machine fdt 解析dtb数据 得到匹配的struct machine desc结构体 这是用来描述板级配置的 early init dt verify
  • Socket连接和Http连接

    Socket连接与HTTP连接 我们在传输数据时 可以只使用 传输层 TCP IP协议 但是那样的话 如果没有应用层 便无法识别数据内容 如果想要使传输的数据有意义 则必须使用到应用层协议 应用层协议有很多 比如HTTP FTP TELNE
  • 分数的拆分原理和方法_四年级数学计算方法和技巧汇总,附口算练习,赶紧给孩子看!...

    简便运算的方法 1 提取公因式 这个方法实际上是运用了乘法分配律 将相同因数提取出来 考试中往往剩下的项相加减 会出现一个整数 注意相同因数的提取 例如 0 92 1 41 0 92 8 59 0 92 1 41 8 59 2 借来借去法
  • java框架之ssh框架之认识

    SSH框架 1 SSH框架是什么 SSH框架是struts spring hibernate的一个集成框架 分为四层 表示层 业务逻辑层 数据持久层和域模块层 其中使用Struts作为系统的整体基础架构 负责MVC的分离 在Struts框架
  • 【实例分割】5、Look Closer to Segment Better

    文章目录 一 背景 二 动机 三 方法 3 1 Boundary Patch Extraction 3 2 Boundary Patch Refinement 3 3 Learning and Inference 四 实验 Paper ht
  • python语法-pyspark实战(数据输出)

    将RDD对象转化为python对象 1 collect算子 collect算子 功能 将RDD各个分区内的数据 统一收集到Driver中 形成一个list对象 用法 rdd collect 返回值是一个list 2 reduce算子 col
  • Jmeter实现登录不同的账号,去完成不同版本的业务流程

    一 思路 通过线程数量去控制你想要登录的用户数量 登录后获取可以区分不同业务流程的字段值 使用循环控制器 在循环控制器下添加if控制器从而去执行不同版本的业务流程 二 简单介绍一下思路中提到插件配置 线程组 方式一 方式二 2 获取登录后的
  • 百元买百鸡4

    题目 公鸡5元钱一只 母鸡3元钱一只 小鸡3只一元钱 用100元钱买一百只鸡 其中公鸡 母鸡 小鸡都必须要有 问公鸡 母鸡 小鸡要买多少只刚好凑足100元钱 思路 公鸡 母鸡 小鸡 100 5 公鸡 3 母鸡 小鸡 3 100 需要两个条件
  • 基于Java平台实现发送短信功能

    首先我们需要一个平台来帮助我们发送短信 而我们是调用它的接口 使用中国网建的SMS平台相对简单 因此需要去平台 https www smschinese com cn reg shtml 注册 1 跳转到注册页面并填写信息 2 注册后点击登
  • 申请软著详细流程

    相信有很多小白和本人一样不知道如何自己申请软著 只要耐心按照读完此文 保证自己可以独立申请啦 如果自己申请的话 目前软著登记是免费的 自己也就付个邮费 如果是加急的话 可以找三方代理机构办理 反正时间越短 价格越高 正常自己申请的话 最后拿
  • jQuery学习

    1 引入jqueryDownload jQuery jQuery 2 是jQuery的别称 以下两种等效 function div hide jQuery function jQuery div hide 3 jQuery对象和DOM对象
  • 线索二叉树(中序、先序和后序及遍历)

    链式存储 线索二叉树是二叉树的一类 在看线索二叉树之前我们先看一下二叉树的链式存储 一个二叉树的存储例子 后面用到的二叉树都是这棵 代码是这样的 public class BinaryTreeNode