学习在白板上写程序

数学归纳法,用于证明断言对所有自然数成立

  • 证明对于N=1成立
  • 证明N>1时:如果对于N-1成立,那么对于N成立

如何证明递归函数正确执行

  • 数学归纳法中的数学、自然语言 <==> 程序语言

递归控制

  • 严格定义递归函数作用,包括参数,返回值,Side-effect
  • 先一般,后特殊
  • 每次调用必须缩小问题规模(如果不这样就成了死循环)
  • 每次问题规模缩小程度必须为1

例一:链表创建

public class Node {

    private final int value;

    private Node next;

    //构造时将next默认为空
    public Node(int value) {
        this.value = value;
        this.next = null;
    }

    public int getValue() {
        return value;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    //打印链表
    public static void printLinkedList(Node head){
        while(head != null){
            System.out.print(head.getValue());
            System.out.print(" ");
            head = head.getNext();
        }
        System.out.println();
    }
}
public class LinkedListCreator {

    /**
     * Creates a linked list.递归
     * @param data the data to create the list
     * @return head of the linked list.The returned linked list
     * ends with last node with getNext() == null
     */
    public Node createLinkedList(List<Integer> data){
        if(data.isEmpty()){
            return null;
        }
        Node firstNode = new Node(data.get(0));
        firstNode.setNext(createLinkedList(data.subList(1,data.size())));
        return firstNode;
    }


    //测试创建链表
    public static void main(String[] args) {
        LinkedListCreator creator = new LinkedListCreator();
        Node.printLinkedList(creator.createLinkedList(new ArrayList<>()));
        Node.printLinkedList(creator.createLinkedList(Arrays.asList(1)));
        Node.printLinkedList(creator.createLinkedList(Arrays.asList(1,2,3,4,5)));

    }
}
  /**
     * 循环创建链表
     * @param data
     * @return
     */
    public Node createLinkedList2(List<Integer> data){
        if(data.isEmpty()){
            return null;
        }
        Node firstNode = new Node(data.get(0));
        //循环创建链表
        Node curNode = firstNode;
        for(int i=1;i<data.size();i++){
            Node nextNode = new Node(data.get(i));
            curNode.setNext(nextNode);
            curNode = nextNode;
        }
        return firstNode;
    }

例二:链表反转

public class LinkedListReverser {

    /**
     * Reaverses a linked list. 递归
     * @param head the linked list to reverse
     * @return head of the reversed linked list
     */
    Node reverseLinkedList(Node head){
        //size == 0 size == 1
        if(head == null || head.getNext() == null){
            return head;
        }

        Node newHead = reverseLinkedList(head.getNext());
        head.getNext().setNext(head);
        head.setNext(null);
        return newHead;
    }

    public static void main(String[] args) {
        LinkedListCreator creator = new LinkedListCreator();
        LinkedListReverser reverser = new LinkedListReverser();
        Node.printLinkedList(reverser.reverseLinkedList(creator.createLinkedList(new ArrayList<>())));
        Node.printLinkedList(reverser.reverseLinkedList(creator.createLinkedList(Arrays.asList(1))));
        Node.printLinkedList(reverser.reverseLinkedList(creator.createLinkedList(Arrays.asList(1,2,3,4,5))));

    }
}
    /**
     * 循环反转链表
     * @param head
     * @return
     */
    Node reverseLinkedList2(Node head){
        Node newHead = null;
        Node curHead = head;
        while(curHead != null){
          Node next = curHead.getNext();
          curHead.setNext(newHead);
          newHead = curHead;
          curHead = next;
        }
        return newHead;
    }

例三:列出所有组合

combinations([1,2,3,4],2)
要点:多个参数的初始值

public class Combinations {

    /**
     * Generates all combinations and output them,
     * selecting n elements from data.
     * @param data
     * @param n
     */
    public void combinations(List<Integer> selected,List<Integer> data, int n){
        //initial value for recursion
        //how to select elements
        //how to output

        if(n ==0 ){
            //output all selected elements
            for(Integer i: selected){
                System.out.print(i);
                System.out.print(" ");
            }
            System.out.println();
            return ;
        }
        if(data.isEmpty()){
            return ;
        }
        // select element 0
        selected.add(data.get(0));
        combinations(selected, data.subList(1,data.size()),n-1);
        // un-select element 0
        selected.remove(selected.size() - 1);
        combinations(selected, data.subList(1,data.size()),n);

    }

    public static void main(String[] args) {
        Combinations comb = new Combinations();
        comb.combinations(new ArrayList<>(),Arrays.asList(1,2,3,4),2);
        System.out.println("=========================");
        comb.combinations(new ArrayList<>(),new ArrayList<>(),0);
        System.out.println("=========================");
        comb.combinations(new ArrayList<>(),new ArrayList<>(),2);
        System.out.println("=========================");
        comb.combinations(new ArrayList<>(),Arrays.asList(1,2,3,4),1);
        System.out.println("=========================");
        comb.combinations(new ArrayList<>(),Arrays.asList(1,2,3,4),0);
        System.out.println("=========================");
    }

}

递归缺点:函数调用开销大,可能会Stack Overflow!
不要尝试递归->非递归

例四:链表删除节点

public Node deleteIfEquals(Node head,int value){
        while(head!=null && head.getValue() == value){
            head = head.getNext();
        }
        Node prev = head;
        if(head == null){
            return null;
        }
        while(prev.getNext() != null){
            if(prev.getNext().getValue() == value){
                prev.setNext(prev.getNext().getNext());
            }else{
                prev = prev.getNext();
            }
        }
        return head;
    }

例: 二分查找

  • 在有序数组中查找元素K,返回K所在下标
  • binarySearch([1,2,10,15,100],15) == 3
   /**
     * 二分查找
     * @param arr 有序
     * @param k
     * @return
     */
    public int binarySearch(int[] arr,int k){

        int a = 0;
        int b = arr.length;
        //[a,b)
        while(a < b){
            //int m = (a + b) / 2;
            int m = a + (b - a) / 2;
            if(k < arr[m]){//a...(m-1)
                b = m;
            }else if(k > arr[m]){//(m+1)...b
                a = m + 1;
            }else{
                return m;
            }
        }
        return -1;
    }

二叉树的遍历

前序遍历:ABDEGCF
中序遍历:DBGEACF
后序遍历:DGEBFCA

/**
 *  树
 * @author WangCH
 * @create 2018-03-14 20:02
 */
public class TreeNode {

    private final char value;

    private TreeNode left;

    private TreeNode right;

    public TreeNode(char value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }

    public char getValue() {
        return value;
    }

    public TreeNode getLeft() {
        return left;
    }

    public void setLeft(TreeNode left) {
        this.left = left;
    }

    public TreeNode getRight() {
        return right;
    }

    public void setRight(TreeNode right) {
        this.right = right;
    }
}
/**
 * 手动创建二叉数
 * @author WangCH
 * @create 2018-03-14 20:03
 */
public class TreeCreator {

    public TreeNode createSampleTree(){
        TreeNode root = new TreeNode('A');
        root.setLeft(new TreeNode('B'));
        root.getLeft().setLeft(new TreeNode('D'));
        root.getLeft().setRight(new TreeNode('E'));
        root.getLeft().getRight().setLeft(new TreeNode('G'));
        root.setRight(new TreeNode('C'));
        root.getRight().setRight(new TreeNode('F'));
        return root;
    }
}
/**
 * @author WangCH
 * @create 2018-03-21 13:46
 */
public class TreeTraversal {

    /**
     * 前序遍历二叉树
     * @param root
     */
    public void preOrder(TreeNode root){
        if(root == null){
            return;
        }
        System.out.print(root.getValue());
        preOrder(root.getLeft());
        preOrder(root.getRight());
    }

    /**
     * 中序遍历
     * @param root
     */
    public void inOrder(TreeNode root){
        if(root == null){
            return;
        }
        inOrder(root.getLeft());
        System.out.print(root.getValue());
        inOrder(root.getRight());
    }

    /**
     * 后序遍历
     * @param root
     */
    public void postOrder(TreeNode root){
        if(root == null){
            return;
        }
        postOrder(root.getLeft());
        postOrder(root.getRight());
        System.out.print(root.getValue());
    }

    public static void main(String[] args) {
        TreeCreator creator = new TreeCreator();
        TreeNode sampleTree= creator.createSampleTree();

        TreeTraversal treeTraversal = new TreeTraversal();
        System.out.print("前序遍历:");
        treeTraversal.preOrder(sampleTree);
        System.out.println();
        System.out.print("中序遍历:");
        treeTraversal.inOrder(sampleTree);
        System.out.println();
        System.out.print("后序遍历:");
        treeTraversal.postOrder(sampleTree);
        System.out.println();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • 课程介绍 先修课:概率统计,程序设计实习,集合论与图论 后续课:算法分析与设计,编译原理,操作系统,数据库概论,人...
    ShellyWhen阅读 2,272评论 0 3
  • 计算机中数的表示及进制转换 数码、基与权数码:表示数的符号基:数码的个数权:每一位所具有的值 各种进制之间的转换 ...
    张轻舟阅读 428评论 0 0
  • NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/...
    蒋昉霖阅读 1,775评论 0 0
  • “一,二,三,好同学们干杯!干杯……愿大家研究生毕业之后,前程似锦,午马凯达。”班长大峰,脸庞洋溢着醉醉的粉羞。 ...
    冯少阅读 825评论 0 1