Java 递归算法的相关实现

Java 递归算法的相关实现

递归本质:程序调用自身的编程技巧叫做递归。
递归的三个条件:1.边界条件 2.递归前进段 3.递归返回段
当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
递归是用栈机制实现的,每深入一层,都要占去一块栈的数据区域。
注意:
1.递归一定要有条件限定,保证递归可以能够停下来,否则会形成死循环并发生栈内存溢出(StackOverflowError)
2.递归中虽然限定了停止下来的条件,但是递归次数不能太多,否则也会发生栈内存溢出
3.禁止构造方法递归
一:递归阶乘

/**阶乘递归实现*/
public static int Factorial(int n){
    if (1==n){//边界条件,阶乘到最后一个数时候返回1
 return 1;
 }else {
        return n*Factorial(n-1);
 }
}

//调用
int content=Factorial(10);
Log.d("aa",content+"");

//结果
aa: 3628800

image.png
二:斐波那契数列
1,1,2,3,5,8,13,21,34,55,89,144和无穷大。这个数列从第3项开始,每一项都等于前两项之和,这一系列数字被称为斐波那契数列,随着数列项数的增加,前一项与后一项之比越来越逼近黄金分割的数值0.6180339887..…

/**斐波那契数列(兔子数列)*/
public static int BirthRabbit(int x){
    if (x==1||x==2){//
        return 1;
 }else {
        return BirthRabbit(x-1)+BirthRabbit(x-2);
 }
}

//调用
for (int i=1;i<=20;i++){
    System.out.println("兔子第" + i + "个月的总数为:" + BirthRabbit(i));//输出20个月,每一个月的兔子数
}
int content=BirthRabbit(10);//输出10个月的兔子数
Log.d("aa",content+"");
//结果
aa: 55

三:汉罗塔问题

/**
 * 汉诺塔问题
 *
 * @param dish 盘子个数(也表示名称)
 * @param from 初始塔座
 * @param temp 中介塔座
 * @param to 目标塔座
 */
public static void move(int dish,String from,String temp,String to){
    if (dish==1){
        System.out.println("将盘子"+dish+"从塔座"+from+"移动到目标塔座"+to);
 }else {
        move(dish-1,from,to,temp);//a为初始塔座,b为目标塔座,c为中介塔座
 System.out.println("将盘子"+dish+"从塔座"+from+"移动到目标"+to);//把a上面的最下面的一个盘子移动到c
 move(dish-1,temp,from,to);//b为初始塔座,c为目标塔座,a为中介塔座
 }
}

//调用
move(3,"A","B","C");

//结果
System.out: 将盘子1从塔座A移动到目标塔座C
System.out: 将盘子2从塔座A移动到目标B
System.out: 将盘子1从塔座C移动到目标塔座B
System.out: 将盘子3从塔座A移动到目标C
System.out: 将盘子1从塔座B移动到目标塔座A
System.out: 将盘子2从塔座B移动到目标C
System.out: 将盘子1从塔座A移动到目标塔座C

四:树的遍历
树的遍历:
1.深度优先(DFS)
1.前序遍历
2.中序遍历
3.后序遍历
2.广度优先(BFS)
1.层次遍历
前提:

//定义节点的数据结构
public class TreeNode {
    String value=null;
 TreeNode leftChildren=null;
 TreeNode rightChildren=null;
 public TreeNode(String value, TreeNode leftChildren, TreeNode rightChildren) {
        this.value = value;
 this.leftChildren = leftChildren;
 this.rightChildren = rightChildren;
 }
    public TreeNode(String value) {
        this.value = value;
 }
    public String getValue() {
        return value;
 }
    public void setValue(String value) {
        this.value = value;
 }
    public TreeNode getLeftChildren() {
        return leftChildren;
 }
    public void setLeftChildren(TreeNode leftChildren) {
        this.leftChildren = leftChildren;
 }
    public TreeNode getRightChildren() {
        return rightChildren;
 }
    public void setRightChildren(TreeNode rightChildren) {
        this.rightChildren = rightChildren;
 }
}

4.1:前序遍历
思路:先根节点-->左子树-->右子树
image.png
实现:

/**创建二叉树*/
public TreeNode getTargetTree() {
    // 叶子节点
 TreeNode G = new TreeNode("G");
 TreeNode D = new TreeNode("D");
 TreeNode E = new TreeNode("E", G, null);
 TreeNode B = new TreeNode("B", D, E);
 TreeNode H = new TreeNode("H");
 TreeNode I = new TreeNode("I");
 TreeNode F = new TreeNode("F", H, I);
 TreeNode C = new TreeNode("C", null, F);
 // 构造根节点
 TreeNode root = new TreeNode("A", B, C);
 return root;
}

/**前序遍历*/
public  void preorderTreeNode(TreeNode node){
    if (null!=node){
        System.out.print(node.value);
 }
    if (null!=node.leftChildren){
        preorderTreeNode(node.leftChildren);//递归实现
 }
    if (null!=node.rightChildren){
        preorderTreeNode(node.rightChildren);//递归实现
 }
}

//调用
TreeNode tree= getTargetTree();//构建树
 System.out.print("前序遍历:");
 preorderTreeNode(tree);
 
 //结果:
 System.out: 前序遍历:ABDEGCFHI

4.2 末子节点遍历

/**前序遍历拿到末节点信息*/
public  void endOrderTreeNode(TreeNode node){
    if (null!=node&&null==node.leftChildren&&null==node.rightChildren){
        System.out.print(node.value);
 }
    if (null!=node.leftChildren){
        endOrderTreeNode(node.leftChildren);
 }
    if (null!=node.rightChildren){
        endOrderTreeNode(node.rightChildren);
 }
}
或者:

/**前序遍历末子节点*/
public  void preorderTreeNode2(TreeNode node){
    if (null==node.leftChildren&&null==node.rightChildren){
        System.out.print(node.value);
 }
  List lists=new ArrayList<>();
 if (null!=node.leftChildren){
        lists.add(node.leftChildren);
 }
    if (null!=node.rightChildren){
        lists.add(node.rightChildren);
 }
    for (int i=0;i

4.3 中序遍历
思路:先左子树-->根节点-->右子树
image.png
实现:

/**
 * 中序遍历
 */
public void inorderTreeNode(TreeNode node){
    if(null != node){
        if(null != node.leftChildren){
            inorderTreeNode(node.leftChildren);
 }
        System.out.print(node.value);
 if(null != node.rightChildren){
            inorderTreeNode(node.rightChildren);
 }
    }
}

//调用
TreeNode tree= getTargetTree();
 System.out.print("中序遍历:");
 inorderTreeNode(tree);
 
 //结果
 中序遍历:DBGEACHFI

4.4 后序遍历
思路:先左子树-->右子树-->根节点
image.png

/**
 * 后序遍历
 */
public void postorderTreeNode(TreeNode node){
    if(null != node){
        if(null != node.leftChildren){
            postorderTreeNode(node.leftChildren);
 }
        if(null != node.rightChildren){
            postorderTreeNode(node.rightChildren);
 }
        System.out.print(node.value);
 }
}

//调用
TreeNode tree= getTargetTree();
 System.out.print("后序遍历:");
 postorderTreeNode(tree);
 
 //结果
 System.out: 后序遍历:DGEBHIFCA

4.5 层次遍历
思路:先根节点,然后第二层,第三层,依次往下走,(同层节点从左往右输出)
image.png

/**
 * 层次遍历
 */
public void levelorderTreeNode(TreeNode node) {
    if (null != node) {
        LinkedList list = new LinkedList();
 list.add(node);//添加当前节点 list.size()为1,添加的当前节点是A
 TreeNode currentNode;
 while (!list.isEmpty()) {
            currentNode = list.poll(); //获取并移除此列表的头部
 System.out.print(currentNode.value);//答应当前节点的值
 if (null != currentNode.leftChildren) {
                list.add(currentNode.leftChildren);//添加左子树到列表尾部
 }
            if (null != currentNode.rightChildren) {
                list.add(currentNode.rightChildren);//添加右子树到列表的尾部
 }
        }
    }
}

//调用
TreeNode tree= getTargetTree();
 System.out.print("层次遍历:");
 levelorderTreeNode(tree);
 
 //结果
 System.out: 层次遍历:ABCDEFGHI

知识点:
1,结点的度: 一个结点含有的子结点的个数称为该结点的度;
2,叶结点或终端结点: 度为0的结点称为叶结点;
3,非终端结点或分支结点: 度不为0的结点;
4,双亲结点或父结点: 若一个结点含有子结点,则这个结点称为其子结点的父结点;
5,孩子结点或子结点: 一个结点含有的子树的根结点称为该结点的子结点;
6,兄弟结点: 具有相同父结点的结点互称为兄弟结点;
7,树的度: 一棵树中,最大的结点的度称为树的度;
8,结点的层次: 从根开始定义起,根为第1层,根的子结点为第2层,以此类推;
9,树的高度或深度: 树中结点的最大层次;
10,堂兄弟结点: 双亲在同一层的结点互为堂兄弟;
11,结点的祖先: 从根到该结点所经分支上的所有结点;
12,子孙: 以某结点为根的子树中任一结点都称为该结点的子孙。
13,森林: 由m(m>=0)棵互不相交的树的集合称为森林;
14,无序树: 树中任意节点的子结点之间没有顺序关系,这种树称为无序树,也称为自由树;
15,有序树: 树中任意节点的子结点之间有顺序关系,这种树称为有序树;
16,二叉树: 每个节点最多含有两个子树的树称为二叉树;
17,完全二叉树: 若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树
18,满二叉树: 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
19,哈夫曼树: 带权路径最短的二叉树称为哈夫曼树或最优二叉树;

END:当你远远凝视深渊时,深渊也在凝视你

你可能感兴趣的:(javaandroid)