Java学习之日撸代码300行(11-20天,线性数据结构)

这篇博客详细介绍了数据结构中的顺序表、链表、栈和队列的基本概念、实现方式以及应用。通过Java代码展示了顺序表的创建、查找、插入和删除功能,链表的结构和操作,栈的入栈、出栈以及括号匹配的应用,以及队列的入队、出队操作。此外,还讨论了面向对象编程的优势和线性表与链表的异同,分析了它们各自的优缺点。
摘要由CSDN通过智能技术生成

原博文:minfanphd

第11天:顺序表(一)

11.1 final关键字的功能概述,参考final关键字的作用(方法、变量、类).:

  • final关键字可以用来修饰引用、方法和类
    • 当用来修饰引用时:
      • 如果引用为基本数据类型,则该引用为常量,该值无法修改。
      • 如果引用为引用数据类型,比如对象、数组,则该对象、数组本身可以修改,但指向该对象或数组的地址的引用不能修改。
      • 如果引用为类的成员变量,则必须当场赋值,否则编译会报错。
    • 当用来修饰方法时:
      • 当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。
    • 当用来修饰类时:
      • 当用final修改类时,该类成为最终类,无法被继承。。

11.2 顺序表是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。顺序存储图如下:
在这里插入图片描述
11.3 通过代码将该数据结构实现出来,在这里其实就体现了面向对象的思想,该数据结构具有数据,长度的特点,因此在构建该类时需要将这些属性给添加进去。

在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:顺序表
 * @author: Qing Zhang
 * @time: 2021/5/23
 */
public class SequentialList {
    public static void main(String[] args) {
        int[] tempArray = {1, 3, 5, 7, 9};
        SequentialList tpFirstList = new SequentialList(tempArray);
        System.out.println("Initialized, the list is: " + tpFirstList.toString());
        System.out.println("Again, the list is: " + tpFirstList);

        tpFirstList.reset();
        System.out.println("After reset, the list is: " + tpFirstList);
    }

    //顺序表的最大长度
    public static final int MAX_LENGTH = 10;

    //用来存储顺序表中的成员数量,当然也可以是数组里的成员数量
    int length;

    //数组,用来存储数据
    int[] data;

    /**
     * @Description: 创建一个空顺序表
     * @Param: []
     * @return:
     */
    public SequentialList() {
        length = 0;
        data = new int[MAX_LENGTH];
    }

    /**
     * @Description: 通过已有的数组去产生一个顺序表
     * @Param: [paraArray]
     * 该数组的长度不能超过MAX_LENGTH
     * @return:
     */
    public SequentialList(int[] paraArray) {
        length = paraArray.length;
        data = new int[MAX_LENGTH];

        //将形参数据复制到data里
        for (int i = 0; i < length; i++) {
            data[i] = paraArray[i];
        }
    }

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

        if (length == 0) {
            return "empty";
        }

        for (int i = 0; i < length - 1; i++) {
            resultString += data[i] + ", ";
        }

        resultString += data[length - 1];

        return resultString;
    }

    /**
     * @Description: 将顺序表置为空
     * @Param: []
     * @return: void
     */
    public void reset() {
        length = 0;
    }
}

第12天:顺序表(二)

12.1 加入了查找功能,根据参数值在顺序表中找出该元素的下标,若未找到就返回-1.
12.2 加入了插入功能,根据给定的合法的下标值以及元素值,插入到相应的位置,其思想就是将该下标以及后面的元素后移一位,前提是有空位置,若数组已经满了那自然就无法插入了。
12.3 加入了删除功能,同上根据给定的合法的下标值,将后面的元素前移一位。
在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:顺序表
 * @author: Qing Zhang
 * @time: 2021/5/23
 */
public class SequentialList {
    public static void main(String[] args) {
        int[] tempArray = {1, 3, 5, 7, 9};
        SequentialList tpFirstList = new SequentialList(tempArray);
        System.out.println("Initialized, the list is: " + tpFirstList.toString());
        System.out.println("Again, the list is: " + tpFirstList);


        int tempValue = 4;
        int tpPosition = tpFirstList.locate(tempValue);
        System.out.println("The position of " + tempValue + " is " + tpPosition);

        tempValue = 5;
        tpPosition = tpFirstList.locate(tempValue);
        System.out.println("The position of " + tempValue + " is " + tpPosition);

        tpPosition = 2;
        tempValue = 5;
        tpFirstList.insert(tpPosition, tempValue);
        System.out.println("After inserting " + tempValue + " to position " + tpPosition
                + ", the list is: " + tpFirstList);

        tpPosition = 8;
        tempValue = 10;
        tpFirstList.insert(tpPosition, tempValue);
        System.out.println("After inserting " + tempValue + " to position " + tpPosition
                + ", the list is: " + tpFirstList);

        tpPosition = 3;
        tpFirstList.delete(tpPosition);
        System.out.println("After deleting data at position " + tpPosition + ", the list is: "
                + tpFirstList);

        for (int i = 0; i < 8; i++) {
            tpFirstList.insert(i, i);
            System.out.println("After inserting " + i + " to position " + i
                    + ", the list is: " + tpFirstList);
        }

        tpFirstList.reset();
        System.out.println("After reset, the list is: " + tpFirstList);
    }

    //顺序表的最大长度
    public static final int MAX_LENGTH = 10;

    //用来存储顺序表中的成员数量,当然也可以是数组里的成员数量
    int length;

    //数组,用来存储数据
    int[] data;

    /**
     * @Description: 创建一个空顺序表
     * @Param: []
     * @return:
     */
    public SequentialList() {
        length = 0;
        data = new int[MAX_LENGTH];
    }

    /**
     * @Description: 通过已有的数组去产生一个顺序表
     * @Param: [paraArray]
     * 该数组的长度不能超过MAX_LENGTH
     * @return:
     */
    public SequentialList(int[] paraArray) {
        length = paraArray.length;
        data = new int[MAX_LENGTH];

        //将形参数据复制到data里
        for (int i = 0; i < length; i++) {
            data[i] = paraArray[i];
        }
    }

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

        if (length == 0) {
            return "empty";
        }

        for (int i = 0; i < length - 1; i++) {
            resultString += data[i] + ", ";
        }

        resultString += data[length - 1];

        return resultString;
    }

    /**
     * @Description: 将顺序表置为空
     * @Param: []
     * @return: void
     */
    public void reset() {
        length = 0;
    }

    /**
     * @Description: 定位元素下标
     * @Param: [paraNum]
     * @return: int
     */
    public int locate(int paraNum) {
        for (int i = 0; i < length; i++) {
            if (data[i] == paraNum) {
                return i;
            }
        }

        return -1;
    }


    /**
     * @Description: 在指定下标插入数值
     * @Param: [paraIndex, paraNum]
     * @return: boolean
     */
    public boolean insert(int paraIndex, int paraNum) {
        if (length == MAX_LENGTH) {
            System.out.println("List full.");
            return false;
        } else if (paraIndex > length || paraIndex < 0) {
            System.out.println("The position " + paraIndex + " is out of bounds.");
            data[length++] = paraNum;
        } else {
            for (int i = length++; i > paraIndex; i--) {
                data[i] = data[i - 1];
            }
            data[paraIndex] = paraNum;
        }
        return true;
    }

    /**
     * @Description: 删除指定下标的元素
     * @Param: [paraIndex]
     * @return: boolean
     */
    public boolean delete(int paraIndex) {
        if (paraIndex >= length || paraIndex < 0) {
            System.out.println("The position " + paraIndex + " is out of bounds.");
            return false;
        } else {
            for (int i = paraIndex; i < length - 1; i++) {
                data[i] = data[i + 1];
            }
            length--;
        }
        return true;
    }
}

第13天:链表

13.1 链表也是线性表的一种,因此其操作与顺序表并无差异。
13.2 在java中采用的是引用的方式,与c/c++中采用指针的方式不同,因此在重置链表时不需要将引用的节点释放,java自带的垃圾回收机制可以自己回收,而后者需要自己去释放。
13.3 链表的特点是方便插入与删除,不需要移动大量元素,但是不易存取,需要挨个遍历才能找到目标元素,而顺序表则正好相反。

  • 垃圾回收机制是jvm自带的一个线程,用于回收没有被引用的对象。

链表结构图
在这里插入图片描述
带头结点的链表图
在这里插入图片描述

在这里插入图片描述
代码:

package DataStructure;

/**
 * @description:链表
 * @author: Qing Zhang
 * @time: 2021/5/25
 */
public class LinkedList {

    //节点类
    class Node {
        //数据
        int data;

        //指向的下一个节点
        Node next;

        /**
         * @Description: 构造函数,用以创造一个节点
         * @Param: [data]
         * @return:
         */
        public Node(int data) {
            this.data = data;
            next = null;
        }

    }

    //头节点,仅方便操作,不使用其数据
    Node header;

    public LinkedList() {
        header = new Node(0);
        //这一步我认为有点多余,因为在new的时候就已经设置next为null了
        header.next = null;
    }

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

        if (header.next == null) {
            return "empty";
        }

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

        return resultString;
    }

    /**
     * @Description: 将链表重置
     * 不过这样好像并没有将去掉的节点释放掉
     * Java有垃圾回收机制,因此不需要像C那样去挨个释放
     * 垃圾回收机制是jvm自带的一个线程,用于回收没有被引用的对象。
     * @Param: []
     * @return: void
     */
    public void reset() {
        header.next = null;
    }

    /**
     * @Description: 定位
     * 未找到就返回-1
     * @Param: [paraValue]
     * @return: int
     */
    public int locate(int paraValue) {
        Node tpNode = header.next;

        for (int i = 0; tpNode != null; tpNode = tpNode.next, i++) {
            if (tpNode.data == paraValue) {
                return i;
            }
        }
        return -1;
    }

    /**
    * @Description: 插入节点
     * 先判断位置是否合法,再将其插入
    * @Param: [paraPosition, paraValue]
    * @return: boolean
    */
    public boolean insert(int paraPosition, int paraValue) {
        Node tpNode = header;
        Node node;

        for (int i = 0; i < paraPosition; i++, tpNode = tpNode.next) {
            if (tpNode == null) {
                System.out.println("The position " + paraPosition + " is illegal.");
                return false;
            }
        }

        node = new Node(paraValue);

        node.next = tpNode.next;
        tpNode.next = node;

        return true;
    }

    /**
    * @Description: 删除节点
     * 先判断位置是否合法,再根据当前节点进行删除
    * @Param: [paraPosition]
    * @return: boolean
    */
    public boolean delete(int paraPosition){

        if (header.next == null) {
            System.out.println("Cannot delete element from an empty list.");
            return false;
        }

        Node curNode = header;

        for (int i = 0; i < paraPosition; i++) {
            if (curNode.next == null) {
                System.out.println("The position " + paraPosition + " is illegal.");
                return false;
            }
            curNode = curNode.next;
        }

        curNode.next = curNode.next.next;

        return true;
    }

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

        for(int i = 0; i < 5; i ++) {
            tempFirstList.insert(0, i);
        }
        System.out.println("Inserted, the list is: " + tempFirstList.toString());

        tempFirstList.delete(2);
        System.out.println("Deleted, the list is: " + tempFirstList.toString());

        tempFirstList.delete(0);
        System.out.println("Deleted, the list is: " + tempFirstList.toString());

        for(int i = 0; i < 5; i ++) {
            tempFirstList.delete(0);
            System.out.println("Looped delete, the list is: " + tempFirstList.toString());
        }
    }
}

第14天:栈

14.1 栈也是一种线性表结构,被称为“操作受限的线性表”,其特点是先进后出。
14.2 栈的应用有很多,包括括号匹配表达式求值递归等。
14.3 栈的种类也有很多,目前我们实现的是顺序栈,还有链栈共享栈

在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:栈
 * 我就很好奇怎么不直接用Stack,原来Java中已经有Stack类了
 * @author: Qing Zhang
 * @time: 2021/5/26
 */
public class CharStack {

    //栈的最大长度
    public static final int MAX_DEPTH = 10;

    //栈的当前长度
    int depth;

    //存储数据
    char[] data;

    /**
    * @Description: 构造函数
    * @Param: []
    * @return:
    */
    public CharStack() {
        depth = 0;
        data = new char[MAX_DEPTH];
    }

    public String toString() {
        if(depth==0){
            return "empty";
        }
        String resultString = "";
        for (int i = 0; i < depth - 1; i++) {
            resultString += data[i] + ", ";
        }
        resultString += data[depth-1];
        return resultString;
    }

    /**
    * @Description: 入栈
    * @Param: [paraValue]
    * @return: boolean
    */
    public boolean push(char paraValue) {
        if (depth == MAX_DEPTH) {
            System.out.println("Stack full.");
            return false;
        }

        data[depth++] = paraValue;

        return true;
    }

    /**
    * @Description: 出栈
     * 将栈顶元素返回,并将栈的长度减一
    * @Param: []
    * @return: char
    */
    public char pop() {
        if (depth == 0) {
            System.out.println("Nothing to pop.");
            return '\0';
        }

        return data[--depth];
    }

    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);
        }

        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);
        }
    }
}

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

15.1 在昨天原有的基础上添加了括号匹配方法,同时修改main函数里的代码用以测试。
15.2 昨天就已经提过括号匹配是栈的应用之一,其主要就是利用其先进后出的特性。
在这里插入图片描述

代码:

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);
        }

//        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);
//        }

        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);
        } 

        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);
    }

    /**
     * @Description: 括号匹配
     * @Param: [paraString]
     * @return: boolean
     */
    public static boolean bracketMatching(String paraString) {
        //先创建一个栈
        CharStack cs = new CharStack();

        char tpChar;

        //再将目标字符串依次入栈出栈比较,一旦遇上一个无法匹配即返回false
        for (int i = 0; i < paraString.length(); i++) {
            tpChar = paraString.charAt(i);
            switch (tpChar) {
                case '(':
                case '[':
                case '{':
                    cs.push(tpChar);
                    break;
                case ')':
                    if (cs.pop() != '(') {
                        return false;
                    }
                    break;
                case ']':
                    if (cs.pop() != '[') {
                        return false;
                    }
                    break;
                case '}':
                    if (cs.pop() != '{') {
                        return false;
                    }
                    break;
                default:
            }
        }

        if (cs.pop() != '\0') {
            return false;
        }

        return true;
    }

第16天: 递归

16.1 毕竟是计算机专业的,因此递归这种东西理解了其实很简单,用我自己的话来说其实就是函数对自己的调用,形成了一种迭代。
16.2 斐波那契数列在递归中拿来练习很常见,这里给出它的公式:
{ f ( 0 ) = 0 , n = 0 f ( 1 ) = 1 , n = 1 f ( n ) = f ( n − 1 ) + f ( n − 2 ) , n > 1 \begin{cases} f(0)=0,\qquad \qquad \qquad \qquad \qquad n=0\\ f(1)=1,\qquad \qquad \qquad \qquad \qquad n=1\\ f(n)=f(n-1)+f(n-2),\qquad n>1 \end{cases} f(0)=0,n=0f(1)=1,n=1f(n)=f(n1)+f(n2),n>1
在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:递归
 * @author: Qing Zhang
 * @time: 2021/5/28
 */
public class Recursion {

    /**
     * @Description: 利用递归求前N项和
     * @Param: [paraN]
     * @return: int
     */
    public static int sumToN(int paraN) {
        if (paraN <= 0) {
            return 0;
        }
        return sumToN(paraN - 1) + paraN;
    }

    /**
    * @Description: 斐波那契函数
     * 基本上递归都会用这个方程来讲解
    * @Param: [paraN]
    * @return: int
    */
    public static int fibonacci(int paraN) {
        if (paraN < 0) {
            return 0;
        } else 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 + " = " + sumToN(tempValue));
        tempValue = -1;
        System.out.println("0 sum to " + tempValue + " = " + sumToN(tempValue));

        for(int i = 0; i < 10; i ++) {
            System.out.println("Fibonacci " + i + ": " + fibonacci(i));
        }
    }
}

第17天: 链队列

17.1 队列也是一种线性表结构,也被称为“操作受限的线性表”,其特点是先进先出,操作受限于队头和队尾。
17.2 队的应用有很多,包括在树中的层次遍历、在计算机系统中可以用来解决主机与外部设备之间速度不匹配的问题、解决多用户引起的资源竞争问题。
17.3 队列的实现方式和种类也有很多,目前我们实现的是链队列,还有循环队列、双端队列。
在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:链队列
 * @author: Qing Zhang
 * @time: 2021/5/29
 */
public class LinkedQueue {

    class Node {
        int data;
        Node next;

        public Node(int data) {
            this.data = data;
            next = null;
        }
    }

    //队头
    Node header;

    //队尾
    Node tail;

    public LinkedQueue() {
        header = new Node(-1);
        header.next = null;

        tail = header;
    }

    /**
    * @Description: 入队
     * 从队尾处添加节点
    * @Param: [data]
    * @return: void
    */
    public void enqueue(int data) {
        Node tpNode = new Node(data);
        tail.next = tpNode;
        tail = tpNode;
    }

    /**
    * @Description: 出队
     * 从队头移除节点
    * @Param: []
    * @return: int
    */
    public int dequeue() {
        if (header.next == null) {
            System.out.println("队列为空");
            return -1;
        }

        int result = header.next.data;
        header.next = header.next.next;
        return result;
    }

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

        if (header.next == null) {
            return "空";
        }

        Node tpNode = header;
        while (tpNode.next != null) {
            resultString += tpNode.next.data + " ";
            tpNode = tpNode.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 new queue is: " + tempQueue.toString());
        }

    }
}

第18天: 循环队列

18.1 在昨天就以及提出了队列的种类,其中就包括循环队列,其主要思想是利用数组存储数据,通过两个下标,即队头下标和队尾下标来控制元素的入队和出队。
18.2 这种方式会浪费掉一个元素空间,因为需要通过判断两个下标的关系来获取循环队列的状态,当队头下标等于队尾下标时,表示此时队列为空;当队尾下标+1==队头下标时,表示此时队列已满,此时队尾下标所占的空间只能搁置,若存储了元素,将导致队头下标等于队尾下标,无法判断队列的真实情况。

在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:循环队列
 * @author: Qing Zhang
 * @time: 2021/5/30
 */
public class CircleQueue {
    public static final int MAX_LENGTH = 10;

    //存储数据
    char[] data;

    //队头下标
    int head;

    //队尾下标
    int tail;

    public CircleQueue() {
        data = new char[MAX_LENGTH];
        head = 0;
        tail = 0;
    }

    /**
     * @Description: 入队
     * @Param: [paraValue]
     * @return: void
     */
    public void enqueue(char paraValue) {
        if ((tail + 1) % MAX_LENGTH == head) {
            System.out.println("队列已满");
            return;
        }

        data[tail % MAX_LENGTH] = paraValue;
        tail++;
    }

    /**
     * @Description: 出队
     * @Param: []
     * @return: int
     */
    public int dequeue() {
        if (head == tail) {
            System.out.println("队列是空的");
            return '\0';
        }

        char result = data[head++];

        return result;
    }

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

        if (head == tail) {
            return "空";
        }

        for (int i = head; i < tail; i++) {
            resultString += data[i % MAX_LENGTH] + " ";
        }
        return resultString;
    }

    public static void main(String[] args) {
        CircleQueue tempQueue = new CircleQueue();
        System.out.println("初始化,该集合为: " + tempQueue.toString());

        for (char i = '0'; i < '5'; i++) {
            tempQueue.enqueue(i);
        }
        System.out.println("入队, 该队列为: " + tempQueue.toString());

        int tempValue = tempQueue.dequeue();
        System.out.println("出队" + tempValue + ", 队列为: " + tempQueue.toString());

        for (char i = 'a'; i < 'f'; i++) {
            tempQueue.enqueue(i);
            System.out.println("入队, 该队列为: " + tempQueue.toString());
        }

        for (int i = 0; i < 3; i++) {
            tempValue = tempQueue.dequeue();
            System.out.println("出队" + tempValue + ", 队列为: " + tempQueue.toString());
        }

        for (char i = 'A'; i < 'F'; i++) {
            tempQueue.enqueue(i);
            System.out.println("入队, 该队列为: " + tempQueue.toString());
        }
    }
}

第19天: 字符串匹配

19.1 串的概念:字符序列,主要关键字为主串、子串、串长。因此这里的字符串的操作主要也是对这些关键字进行操作,包括串长,切割子串,匹配子串。
19.2 匹配子串的方法又称为模式匹配算法,包括以下算法:

  • 暴力匹配算法:就是挨个匹配判断,时间复杂度较高,在字符串比较短时效果较好。
  • KMP算法:主要是将目标子串的next数组求解出来用以与字符串匹配,这里的next数组请自行查询。
  • KMP算法改进:next数组变成了nextval数组,详情同上。

19.3 本文中采用的便是暴力匹配算法。

在这里插入图片描述

代码:

package DataStructure;

/**
 * @description:字符串匹配
 * @author: Qing Zhang
 * @time: 2021/5/30
 */
public class MyString {
    //字符串的最大长度
    public static final int MAX_LENGTH = 10;

    //实际的字符串长度
    int length;

    //存储字符
    char[] data;

    /**
     * @Description: 构造函数
     * @Param: []
     * @return:
     */
    public MyString() {
        length = 0;
        data = new char[MAX_LENGTH];
    }

    /**
     * @Description: 构造函数
     * @Param: [paraString]
     * 该字符串的长度应不超过最大字符串长度
     * @return:
     */
    public MyString(String paraString) {
        data = new char[MAX_LENGTH];
        length = paraString.length();

        //将数据复制到数组中
        for (int i = 0; i < length; i++) {
            data[i] = paraString.charAt(i);
        }
    }

    /**
     * @Description: 重载
     * @Param: []
     * @return: java.lang.String
     */
    public String toString() {
        String resultString = "";

        for (int i = 0; i < length; i++) {
            resultString += data[i];
        }

        return resultString;
    }

    /**
     * @Description: 字符串匹配
     * 采用的是暴力匹配
     * @Param: [paraMyString]
     * @return: int
     */
    public int locate(MyString paraMyString) {
        boolean tempMatch = false;

        //暴力匹配
        for (int i = 0; i < length - paraMyString.length + 1; i++) {
            tempMatch = true;
            for (int j = 0; j < paraMyString.length; j++) {
                if (data[i + j] != paraMyString.data[j]) {
                    tempMatch = false;
                    break;
                }
            }
            if (tempMatch) {
                return i;
            }
        }

        return -1;
    }

    /**
    * @Description: 由起始位置以及切割长度切割字符串
    * @Param: [paraStartPosition, paraLength]
    * @return: DataStructure.MyString
    */
    public MyString subString(int paraStartPosition, int paraLength) {
        if (paraStartPosition + paraLength > length) {
            System.out.println("越界警告!!!");
            return null;
        }

        MyString resMyString = new MyString();
        resMyString.length = paraLength;

        for (int i = 0, j = paraLength; i < paraLength; i++, j++) {
            resMyString.data[i] = data[j];
        }

        return resMyString;
    }

    public static void main(String[] args) {
        MyString tempFirstString = new MyString("I like ik.");
        MyString tempSecondString = new MyString("ik");
        int tempPosition = tempFirstString.locate(tempSecondString);
        System.out.println("The position of \"" + tempSecondString + "\" in \"" + tempFirstString
                + "\" is: " + tempPosition);

        MyString tempThirdString = new MyString("ki");
        tempPosition = tempFirstString.locate(tempThirdString);
        System.out.println("The position of \"" + tempThirdString + "\" in \"" + tempFirstString
                + "\" is: " + tempPosition);

        tempThirdString = tempFirstString.subString(1, 2);
        System.out.println("The substring is: \"" + tempThirdString + "\"");

        tempThirdString = tempFirstString.subString(5, 5);
        System.out.println("The substring is: \"" + tempThirdString + "\"");

        tempThirdString = tempFirstString.subString(5, 6);
        System.out.println("The substring is: \"" + tempThirdString + "\"");
    }
}

第 20 天: 综合任务 2

面向对象与面向过程相比, 有哪些优势? 注: 第 1 - 10 天的程序, 就是面向过程的.

面向过程写的代码复用性较差,但面向对象的复用性更强。

比较线性表和链表的异同.

线性表主要是逻辑上与物理上连续,而后者是逻辑上连续,物理上随机分配。

分析线性表和链表的优缺点.

线性表优点是易存取,缺点是不易插入与删除,需要移动大量的元素。
链表的优点是方便插入与删除,不需要移动大量元素,缺点是不易存取,需要挨个遍历才能找到目标元素。

分析调拭程序常见的问题及解决方案.

操作链表这类数据结构时通常需要考虑空指针。

分析链队列与循环队列的优缺点.

链队列优点是更加灵活,可以随意拓展长度,缺点是入队出队都会申请内存,产生一定的时间消耗。
循环队列优点是提前申请内存,可以有效地利用资源,缺点是判断队列满时需要浪费掉一个空间。

第 18 天建立的两个队列, 其区别仅在于基础数据不同, 一个是 int, 一个是 char. 按这种思路, 对于不同的基础数据类型, 都需要重写一个类, 这样合理吗? 你想怎么样?

不合理,这产生了大量重复的工作。我认为可以直接用Object类型,因为其它数据类型都继承自它,因此可以通过强制转换为目标数据类型即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值