跟着我爹学Java 14-17天

第 14 天: 栈

14.1 push 和 pop 均只能在栈顶操作.
14.2 没有循环, 时间复杂度为 O ( 1 ) O(1)O(1).

第 15 天: 栈的应用(括号匹配)

任务描述: 检查一个字符串的括号是否匹配. 所谓匹配, 是指每个左括号有相应的一个右括号与之对应, 且左括号不可以出现在右括号右边. 可以修改测试字符串, 检查不同情况下的运行.
15.1 仅在昨天的代码基础上增加了一个 bracketMatching 方法, 以及 main 中的相应调拭语句.
15.2 操作系统的核心数据结构. 对于计算机而言, 如何降低时间、空间复杂度才是王道.
15.3 除了关注的括号, 其它字符不起任何作用.
15.4 一旦发现不匹配, 就直接返回, 不用罗嗦. 

package linear_data_structure;

public class CharStack {
    //The depth.
    public static final int MAX_DEPTH = 10;
    //The actual depth.
    int depth;
    //The data
    char[] data;

    //Construct an empty char stack.
    public CharStack() {
        depth = 0;
        data = new char[MAX_DEPTH];
    }

    //Overrides the method claimed in Object, the superclass of any class.
    public String toString() {
        String resultString = "";
        for (int i = 0; i < depth; i++) {
            resultString += data[i];
        }
        return resultString;
    }

    //push
    //@param paraChar The given char.
    //@return Success or not.

    public boolean push(char parachar) {
        if (depth == MAX_DEPTH) {
            System.out.println("Stack full.");
            return false;
        }
        data[depth] = parachar;
        depth++;
        return true;
    }

    //pop
    public char pop() {
        if (depth == 0) {
            System.out.println("Nothing to pop.");
            return '\0';
        }
        depth--;
        return data[depth];
    }

    public static boolean bracketMatching(String paraString) {
        //Step 1. Initialize the stack through pushing a '#' as a buttom
        CharStack tempStack = new CharStack();
        tempStack.push('#');
        char tempChar, tempPopedChar;

        //Step 2. Process the string. For a string,length() is a method
        //instead of a member variable.
        for (int i = 0; i < paraString.length(); i++) {
            tempChar = paraString.charAt(i);

            switch (tempChar) {
                case '(', '[', '{':
                    tempStack.push(tempChar);
                    break;
                case ')':
                    tempPopedChar = tempStack.pop();
                    if (tempPopedChar != '(') {
                        return false;
                    }
                    break;
                case ']':
                    tempPopedChar = tempStack.pop();
                    if (tempPopedChar != '[') {
                        return false;
                    }
                    break;
                case '}':
                    tempPopedChar = tempStack.pop();
                    if (tempPopedChar != '{') {
                        return false;
                    }
                    break;
                default:
                    //Do nothing.
            }

        }
        tempPopedChar = tempStack.pop();
        if (tempPopedChar != '#') {
            return false;
        }
        return true;
    }

    public static void main(String args[]) {
        CharStack tempStack = new CharStack();

        for (char ch = 'a'; ch < 'm'; ch++) {
            tempStack.push(ch);
            System.out.println("The current stack is: " + tempStack);
        } // Of for i

        char tempChar;
        for (int i = 0; i < 12; i++) {
            tempChar = tempStack.pop();
            System.out.println("Poped: " + tempChar);
            System.out.println("The current stack is: " + tempStack);
        } // Of for i

        boolean tempMatch;
        String tempExpression = "[2 + (1 - 3)] * 4";
        tempMatch = bracketMatching(tempExpression);
        System.out
                .println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);

        tempExpression = "( )  )";
        tempMatch = bracketMatching(tempExpression);
        System.out
                .println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);

        tempExpression = "()()(())";
        tempMatch = bracketMatching(tempExpression);
        System.out
                .println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);

        tempExpression = "({}[])";
        tempMatch = bracketMatching(tempExpression);
        System.out
                .println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);

        tempExpression = ")(";
        tempMatch = bracketMatching(tempExpression);
        System.out
                .println("Is the expression " + tempExpression + " bracket matching? " + tempMatch);
    }// Of main
}

栈:首先定义一个最大深度,成员变量有depth和一个字符串数组,然后定义空参构造,成员方法有toString/push/pop

字符串匹配定义一个boolean成员方法,先输入一个‘#’,switch语句进行匹配。

第 16 天: 递归

16.1 递归这个东东, 能理解的同学秒懂, 理解不了的就简直没任何办法.
16.2 数学式子写出来了, 直接翻译成程序, 简单方便.
16.3 系统会为递归建栈, 这个需要理解一下. 例如, 累加程序, 空间复杂度是 O ( n ) O(n)O(n), 因为只有运行到 paraN = 1 时, 才会弹栈.
16.4 Hanoi 问题虽然很有名, 但它更多的是对形参/实参的理解, 所以不写在这里给读者添堵. 再说了, 那种极端的例子也不具有代表性. 

package linear_data_structure;

public class Recursion {
    //Sum to N. No loop, however a stack is used.
    public static int sumTnN(int paraN) {
        if (paraN <= 0) {
            return 0;
        }
        return   sumTnN(paraN-1) + paraN;
    }

    //fibonacci
    public static int fibonacci(int paraN) {
        if (paraN <= 0) {
            return 0;
        }
        if (paraN == 1) {
            return 1;
        }
        return fibonacci(paraN - 1) + fibonacci(paraN - 2);

    }

    public static void main(String[] args) {
        int tempValue = 5;
        System.out.println("0 sum to " + tempValue + " = " + sumTnN(tempValue));
        tempValue = -1;
        System.out.println("0 sum to " + tempValue + " = " + sumTnN(tempValue));
        for (int i = 0; i < 10; i++) {
            System.out.println("Fibonacci " + i + ": " + fibonacci(i));
        }
    }
}

递归Recursion,在c语言和py中已经用过很多了,这里不在赘述

第 17 天: 链队列

17.1 链队列比较容易写.
17.2 Node 类以前是 LinkdedList 的内嵌类, 这里重写了一遍. 访问控制的事情以后再说.
17.3 为方便操作, 空队列也需要一个节点. 这和以前的链表同理. 头节点的引用 (指针) 称为 header.
17.4 入队仅操作尾部, 出队仅操作头部.

package linear_data_structure;

public class LinkedQueue {

    class Node {
        int data;
        Node next;

        public Node(int paraValue) {
            data = paraValue;
            next = null;

        }
    }

    Node header;
    Node tail;

    public LinkedQueue() {
        header = new Node(-1);
        tail = header;
    }

    public void enqueue(int paraValue) {
        Node tempNode = new Node(paraValue);
        tail.next = tempNode;
        tail = tempNode;
    }

    public int dequeue() {
        if (header == tail) {
            System.out.println("No element in the queue");
            return -1;
        }
        int resultValue = header.next.data;
        header.next = header.next.next;

        if (header.next == null) {
            tail = header;
        }
        return resultValue;

    }

    public String toString() {
        String resultString = "";

        if (header.next == null) {
            System.out.println("empty");
        }

        Node tempNode = header.next;
        while (tempNode != null) {
            resultString += tempNode.data + ", ";
            tempNode = tempNode.next;
        }
        return resultString;
    }

    public static void main(String[] args) {
        LinkedQueue tempQueue = new LinkedQueue();
        System.out.println("Initialized, the list is: " + tempQueue.toString());

        for (int i = 0; i < 5; i++) {
            tempQueue.enqueue(i+1);
        }
        System.out.println("Enqueue, the queue is: " + tempQueue.toString());

        tempQueue.dequeue();
        System.out.println("Dequeue, the queue is: " + tempQueue.toString());

        int tempValue;
        for (int i = 0; i < 5; i++) {
            tempValue = tempQueue.dequeue();
            System.out.println("Looped delete " + tempValue + ",the queue is: " + tempQueue.toString());

        }
        for (int i = 0; i < 3; i++) {
            tempQueue.enqueue(i + 10);
        } // Of for i
        System.out.println("Enqueue, the queue is: " + tempQueue.toString());

    }
}

在链队列这个应用类中,首先定义Node类,Node类中包括成员变量和全参构造方法,然后定义链队列的成员变量:header和tail,空参构造,成员方法enqueue、dequeue、toString。

要注意的是,队列中永远有个多的节点,也就是空队列中也有一个节点使头尾节点指向它,tail节点指向最后包含数据元素的节点,而header节点指向多的那个节点,header节点的next节点才是指向第一个包含数据元素的节点。

另外,注意空队列的状态,使头尾节点指向同一节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值