JavaDay4

学习来源:日撸 Java 三百行(11-20天,线性数据结构)_闵帆的博客——CSDN博客

一、操作受限的线性表——栈

1. 栈的定义

        栈是一种只允许在一端进行插入和删除操作的线性表。允许进行插入和删除操作的一端称为栈顶,对应的另一端为栈底。栈的特点是后进先出(后进进栈的元素会比先进栈的元素先出栈)。

2. 栈有初始化、进栈、出栈、读栈顶等操作。

package JavaDay4;

/**
 * @author Kexiong Wang
 *
 * @date 2022年4月17日
 */
public class Stack {
    //栈的空间上限
    public static final int MAX_SIZE = 10;

    //栈顶
    int top;

    //栈的存储空间
    char[] data;

    /**
     ***********
     * 栈的构造函数
     * 创建一个空栈
     ***********
     */
    public Stack() {
        top = -1;
        data = new char[MAX_SIZE];
    }//Of Stack

    /**
     ***********
     * 重写toString方法,将栈中元素以字符串输出
     ***********
     */
    public String toString() {
        String resultString = "";

        if(top ==  -1) {
            return "Empty";
        }//Of if

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

        return resultString;
    }//Of toString

    /**
     ***********
     * 入栈
     *
     * @param paraChar  入栈元素
     * @return          返回入栈结果
     ***********
     */
    public boolean push(char paraChar) {
        if(top + 1 == MAX_SIZE) {
            System.out.println("Stack is full!");
            return false;
        }//Of if

        data[++top] = paraChar;

        return true;
    }//Of push

    /**
     ***********
     * 出栈
     *
     * @return  返回出栈元素
     ***********
     */
    public char pop() {
        if(top == -1) {
            System.out.println("Stack is empty!");
            return '\0';
        }//Of if

        char tempChar = data[top--];

        return tempChar;
    }//Of pop

    /**
     ***********
     * 程序入口
     *
     * @param args  暂未使用
     ***********
     */
    public static void main(String[] args) {
        Stack stack = new Stack();
        System.out.println("The initialized stack is: " + stack.toString());

        for(char ch = 'a';ch < 'h'; ch ++) {
            stack.push(ch);
        }//Of for ch
        System.out.println("After pushed, the stack is: " + stack.toString());

        char tempChar = stack.pop();
        System.out.println("The top is: " + tempChar + ", after popped, the stack is: " + stack.toString());
    }//Of main
}//Of class Stack

运行结果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnV0dGVyZmZmbHk=,size_15,color_FFFFFF,t_70,g_se,x_16

3. 栈的应用——括号匹配 

package JavaDay4;

/**
 * @author Kexiong Wang
 *
 * @date 2022年4月17日
 */
public class StackForBracketMatching {
    //栈的空间上限
    public static final int MAX_SIZE = 10;

    //栈顶
    int top;

    //栈的存储空间
    char[] data;

    /**
     ***********
     * 栈的构造函数
     * 创建一个空栈
     ***********
     */
    public StackForBracketMatching() {
        top = -1;
        data = new char[MAX_SIZE];
    }//Of StackForBracketMatching

    /**
     ***********
     * 重写toString方法,将栈中元素以字符串输出
     ***********
     */
    public String toString() {
        String resultString = "";

        if(top ==  -1) {
            return "Empty";
        }//Of if

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

        return resultString;
    }//Of toString

    /**
     ***********
     * 入栈
     *
     * @param paraChar  入栈元素
     * @return          返回入栈结果
     ***********
     */
    public boolean push(char paraChar) {
        if(top + 1 == MAX_SIZE) {
            System.out.println("Stack is full!");
            return false;
        }//Of if

        data[++top] = paraChar;

        return true;
    }//Of push

    /**
     ***********
     * 出栈
     *
     * @return  返回出栈元素
     ***********
     */
    public char pop() {
        if(top == -1) {
            System.out.println("Stack is empty!");
            return '\0';
        }//Of if

        char tempChar = data[top--];

        return tempChar;
    }//Of pop

    /**
     ***********
     * 括号匹配
     *
     * @param paraString  传入的进行括号匹配的表达式
     * @return            是否匹配
     ***********
     */
    public boolean isMatch(String paraString) {
        StackForBracketMatching stack = new StackForBracketMatching();
        stack.push('#');

        char tempPushChar,tempPopChar;

        for(int i = 0; i < paraString.length(); i++) {
            tempPushChar = paraString.charAt(i);

            switch (tempPushChar) {
                case '(':
                case '[':
                case '{':
                    stack.push(tempPushChar);
                    break;
                case ')':
                    tempPopChar = stack.pop();
                    if(tempPopChar != '(') {
                        return false;
                    }//Of if
                    break;
                case ']':
                    tempPopChar = stack.pop();
                    if(tempPopChar != '[') {
                        return false;
                    }//Of if
                    break;
                case '}':
                    tempPopChar = stack.pop();
                    if(tempPopChar != '{') {
                        return false;
                    }//Of if
                    break;
                default:
            }//Of switch
        }//Of for i

        tempPopChar = stack.pop();
        if(tempPopChar != '#') {
            return false;
        }//Of if

        return true;
    }//Of isMatch

    /**
     ***********
     * 程序入口
     *
     * @param args  暂未使用
     ***********
     */
    public static void main(String[] args) {
        StackForBracketMatching stack = new StackForBracketMatching();

        String tempString1 = "[2 * (1 + 1)]";
        System.out.print("The tempString " + tempString1 + " is ");
        if(!stack.isMatch(tempString1)) {
            System.out.print("not ");
        }//Of if
        System.out.println("bracket matching.");

        String tempString2 = "[2 * (1 + 1)}";
        System.out.print("The tempString " + tempString2 + " is ");
        if(!stack.isMatch(tempString2)) {
            System.out.print("not ");
        }//Of if
        System.out.println("bracket matching.");
    }//Of main
}//Of class StackBracketMatching

运行结果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnV0dGVyZmZmbHk=,size_17,color_FFFFFF,t_70,g_se,x_16

4. 栈的应用——递归 

        递归是指在一个函数、过程或数据结构的定义中又应用了自身,则这个函数、过程或数据结构就称是递归定义的。递归可以将一个大型的复杂问题转化为层层嵌套的规模较小的问题,很大程度得减少了代码量,但效率普遍不高。

package JavaDay4;

/**
 * @author Kexiong Wang
 *
 * @date 2022年4月17日
 */
public class StackForRecursion {
    /**
     ***********
     * 1到n的累加
     *
     * @param paraValue  给定的累加上限
     * @return           累加的和
     ***********
     */
    public static int sumToN(int paraValue) {
        if(paraValue <= 0) {
            return 0;
        }//Of if

        return sumToN(paraValue - 1) + paraValue;
    }//Of sumToN

    /**
     ***********
     * 斐波那契数列
     *
     * @param paraValue  给定的值
     * @retuen           数列某项值
     ***********
     */
    public static int sumFibonacci(int paraValue) {
        if(paraValue <= 0) {
            return 0;
        }//Of if

        if(paraValue == 1) {
            return 1;
        }//Of if

        return sumFibonacci(paraValue - 1) + sumFibonacci(paraValue - 2);
    }//Of sumFibonacci

    /**
     ***********
     * 程序入口
     *
     * @param args  暂未使用
     ***********
     */
    public static void main(String[] args) {
        int tempValue1 = 20;
        int tempValue2 = 8;

        System.out.println("Add from 1 to 20 is: " + sumToN(tempValue1));
        System.out.println("The 8th number of fibonacci is: " + sumFibonacci(tempValue2));
    }//Of main
}//Of class StackForRecursion

运行结果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnV0dGVyZmZmbHk=,size_12,color_FFFFFF,t_70,g_se,x_16

二、操作受限的线性表——队列

1. 队列的定义

        队列只允许在表的一端进行插入,在另一端进行删除。插入元素称入队,删除元素称出队。队列的特点是先进先出。

2. 队列的顺序存储

package JavaDay4;

/**
 * @author Kexiong Wang
 *
 * @date 2022年4月17日
 */
public class SequenceQueue {
    //最大队长
    public static final int MAX_SIZE = 10;

    //队头
    int front;
    //队尾
    int rear;

    //队列存储空间
    char[] data;

    /**
     ***********
     * 初始化
     ***********
     */
    public SequenceQueue() {
        front = rear = 0;
        data = new char[MAX_SIZE];
    }//Of SequenceQueue

    /**
     ***********
     * 输出队列的toString方法
     ***********
     */
    public String toString() {
        String resultString = "";

        if(front == rear) {
            return "The queue is empty!";
        }//Of if

        for(int i = front; i < rear; i ++) {
            resultString += data[i];
        }//Of for i

        return resultString;
    }//Of toString

    /**
     ***********
     * 入队
     *
     * @param paraCh  入队的元素
     * @return           入队是否成功
     ***********
     */
    public boolean enQueue(char paraCh) {
        if(rear >= MAX_SIZE) {
            System.out.println("The queue is full!");
            return false;
        }//Of if

        data[rear++] = paraCh;

        return true;
    }//Of enQueue

    /**
     ***********
     * 出队
     *
     * @return  出队是否成功
     ***********
     */
    public boolean deQueue() {
        if(front == rear) {
            System.out.println("The queue is empty!");
            return false;
        }//Of if

        front ++;

        return true;
    }//Of deQueue

    /**
     ***********
     * 程序入口
     *
     * @param args  暂未使用
     ***********
     */
    public static void main(String[] args) {
        SequenceQueue sequenceQueue = new SequenceQueue();
        System.out.println("After initialized, the queue is: " + sequenceQueue.toString());

        for(char ch = 'a'; ch < 'h'; ch ++) {
            sequenceQueue.enQueue(ch);
        }//Of for ch
        System.out.println("After enqueue, the queue is: " + sequenceQueue.toString());

        sequenceQueue.deQueue();
        System.out.println("After dequeue, the queue is: " + sequenceQueue.toString());
    }//Of main
}//Of class SequenceQueue

运行结果 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnV0dGVyZmZmbHk=,size_16,color_FFFFFF,t_70,g_se,x_16

3. 循环队列

        在使用顺序队列过程中发现,在队列经过若干次的入队出队操作后,出现rear=MAX_SIZE的情况,此时无法再进行入队操作,但队列中可能还存在可以存储元素的空间。

        为了解决上述问题,引入循环队列的概念。循环队列并不是物理上的循环,而是把存储队列元素的表在逻辑上视为一个环。

package JavaDay4;

import javax.annotation.processing.SupportedSourceVersion;

/**
 * @author Kexiong Wang
 *
 * @date 2022年4月17日
 */
public class CircleQueue {
    //最大队长
    public static final int MAX_SIZE = 10;

    //队头
    int front;
    //队尾
    int rear;

    //队列存储空间
    char[] data;

    /**
     ***********
     * 初始化
     ***********
     */
    public CircleQueue() {
        front = rear = 0;
        data = new char[MAX_SIZE];
    }//Of CircleQueue

    /**
     ***********
     * 输出队列的toString方法
     ***********
     */
    public String toString() {
        String resultString = "";

        if(front == rear) {
            return "The queue is empty!";
        }//Of if

        if(front < rear) {
            for(int i = front; i < rear; i ++) {
                resultString += data[i];
            }//Of for i
        } else {
            for(int j = front; j < MAX_SIZE; j ++) {
                resultString += data[j];
            }//Of for j

            for(int k = 0; k < rear; k ++) {
                resultString += data[k];
            }//Of for k
        }//Of if else

        return resultString;
    }//Of toString

    /**
     ***********
     * 入队
     *
     * @param paraCh  入队的元素
     * @return           入队是否成功
     ***********
     */
    public boolean enQueue(char paraCh) {
        if(((rear + 1) % 10) == front) {
            System.out.println("The queue is full!");
            return false;
        }//Of if

        data[rear] = paraCh;

        rear = (rear + 1) % 10;

        return true;
    }//Of enQueue

    /**
     ***********
     * 出队
     *
     * @return  出队是否成功
     ***********
     */
    public boolean deQueue() {
        if(front == rear) {
            System.out.println("The queue is empty!");
            return false;
        }//Of if

        front = (front + 1) % 10;

        return true;
    }//Of deQueue

    /**
     ***********
     * 程序入口
     *
     * @param args  暂未使用
     ***********
     */
    public static void main(String[] args) {
        CircleQueue circleQueue = new CircleQueue();
        System.out.println("After initialized, the queue is: " + circleQueue.toString());

        for(char ch = 'a'; ch < 'j'; ch ++) {
            circleQueue.enQueue(ch);
        }//Of for ch
        System.out.println("After enqueue, the queue is: " + circleQueue.toString());

        System.out.print("Attempt to enqueue character x: ");
        circleQueue.enQueue('x');

        circleQueue.deQueue();
        circleQueue.enQueue('x');
        System.out.println("After dequeue and enqueue character x, the queue is: " + circleQueue.toString());
    }//Of main
}//Of class CircleQueue

运行结果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnV0dGVyZmZmbHk=,size_19,color_FFFFFF,t_70,g_se,x_16

三、线性表应用——字符串匹配

package JavaDay4;

/**
 * @author Kexiong Wang
 *
 * @date 2022年4月17日
 */
public class MyString {
    //最大长度
    public static final int MAX_LENGTH = 10;
    //实际长度
    int length;
    //存字符串
    char[] data;

    /**
     ***********
     * 无参构造函数,创建空字符串
     ***********
     */
    public MyString() {
        length = 0;
        data = new char[MAX_LENGTH];
    }//Of MyString

    /**
     ***********
     * 带参构造函数
     *
     * @param paraString  用来初始化的字符串
     ***********
     */
    public MyString(String paraString) {
        length = paraString.length();
        data = new char[MAX_LENGTH];

        for(int i = 0; i < length; i ++) {
            data[i] = paraString.charAt(i);
        }//Of for i
    }//Of MyString

    /**
     ***********
     * 转为字符串
     ***********
     */
    public String toString() {
        String resultString = "";

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

        return resultString;
    }//Of toString

    /**
     ***********
     * 定位子串
     *
     * @param subString  要查找的子串
     * @return           第一个匹配子串的位置,-1表示为匹配到子串
     ***********
     */
    public int subStringMatch(MyString subString) {
        boolean flag = false;

        for(int i = 0; i <= (length - subString.length); i ++) {
            flag = true;

            for(int j = 0; j < subString.length; j ++) {
                if(data[i + j] != subString.data[j]) {
                    flag = false;
                    break;
                }//Of if
            }//Of for j

            if(flag) {
                return i + 1;
            }//Of if
        }//Of for i

        return -1;
    }//Of subStringMatch

    /**
     ***********
     * 截取子串
     *
     * @param paraPosition  截取子串的起点
     * @param paraLength    截取子串的长度
     ***********
     */
    public MyString subString(int paraPosition, int paraLength) {
        if((paraPosition - 1 + paraLength) > length) {
            System.out.println("The bound is exceeded!");
            return null;
        }//Of if

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

        for(int i = 0; i < paraLength; i ++) {
            resultString.data[i] = data[paraPosition - 1 +i];
        }//Of for i

        return resultString;
    }//Of subString

    /**
     ***********
     * 程序入口
     *
     * @param args  暂未使用
     ***********
     */
    public static void main(String[] args) {
        MyString myString = new MyString("Iambruce");
        MyString subString = new MyString("uce");
        System.out.println("The position of \"" + subString + "\" in \"" + myString + "\" is " + myString.subStringMatch(subString));

        int paraPosition = 4;
        int paraLength = 5;
        System.out.println("The substring of \"" + myString + "\" from " + paraPosition + " to " + 9 + " is \"" + myString.subString(paraPosition,paraLength) + "\"");
    }//Of main
}//Of class MyString

运行结果

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnV0dGVyZmZmbHk=,size_16,color_FFFFFF,t_70,g_se,x_16

四、总结

        主要学习了操作受限的线性表——栈的队列的基本添加元素、删除元素的操作。以及栈和队列的应用。

        其中顺序栈与链栈(顺序队列、循环队列与链队列)的区别从本质上来说是顺序表与链表的区别。顺序表的优点是逻辑结构与物理结构具有一致性,方便查找元素。而链表的优点在于添加和删除元素时的操作较顺序表要简单许多。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值