数据结构02

中缀转后缀

package p2.线性结构;
//中缀表达式转后缀表达式
public class InfixToSuffix {
    public static void main(String[] args) {
        String expression = "(10+20/2*3)/2+8";
        expression = infixToSuffix(expression);
        System.out.println(expression);
    }
    static String infixToSuffix(String expression) {
        //操作符的栈
        ArrayStack<String> opStack = new ArrayStack<>();
        //后缀表达式的线性表
        ArrayList<String> suffixList = new ArrayList<>();

        //格式化表达式
        expression = insertBlanks(expression);
        String[] tokens = expression.split(" ");
        for (String token : tokens) {
            //过滤空串
            if (token.length() == 0) {
                continue;
            }
            //判断操作符+ - * /
            if (isOperator(token)) {
                /*
                什么时候操作符进栈?
                1.如果栈为空
                2.如果栈顶是 (
                3.如果栈顶是操作符,且优先级比当前token小

                什么时候需要将栈顶操作符出栈?
                1.栈顶操作符的优先级 >= 当前token
                */
                while (true) {
                    if (opStack.isEmpty() || opStack.peek().equals("(") || priority(opStack.peek()) < priority(token)) {
                        opStack.push(token);
                        break;
                    }
                    suffixList.add(opStack.pop());
                }
            } else if (token.equals("(")) {
                opStack.push(token);
            } else if (token.equals(")")) {
                while (!opStack.peek().equals("(")) {
                    suffixList.add(opStack.pop());
                }
                opStack.pop();
            } else if (isNumber(token)) {
                suffixList.add(token);
            } else {
                throw new IllegalArgumentException("wrong char :" + expression);
            }
        }
        while (!opStack.isEmpty()) {
            suffixList.add(opStack.pop());
        }
        //将数字元素和操作符元素进行拼接
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < suffixList.size(); i++) {
            sb.append(suffixList.get(i));
            sb.append(' ');
        }
        return sb.toString();
    }

    private static int priority(String token) {
        if (token.equals("+") || token.equals("-")) {
            return 0;
        }
        if (token.equals("*") || token.equals("/")) {
            return 1;
        }
        return -1;
    }

    private static boolean isNumber(String token) {
        return token.matches("\\d+");
    }

    private static boolean isOperator(String token) {
        return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
    }

    //对原表达式进行格式化处理 给所有的非数字字符两边添加空格
    private static String insertBlanks(String expression) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
                sb.append(' ');
                sb.append(c);
                sb.append(' ');
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

后缀计算器

package p2.线性结构;
//中缀表达式计算器
public class InfixCalculator {
    public static void main(String[] args) {
        String expression = "(10+20/2*3)/2+8";
        try{
            int result = evaluateExpression(expression);
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("Wrong expression:" + expression);
        }
    }

    private static int evaluateExpression(String expression) {
        //需要两个辅助栈
        ArrayStack<Character> operatorStack = new ArrayStack<>();
        ArrayStack<Integer> numberStack = new ArrayStack<>();
        //格式化表达式
        expression = insertBlanks(expression);
        String[] tokens = expression.split(" ");
        for (String token : tokens){
            //过滤空串
            if(token.length() == 0){
                continue;
                //遍历 + -号
                //如果之前是+-*/需要弹栈计算
            }else if(token.equals("+") || token.equals("-")){
                while (!operatorStack.isEmpty() && (operatorStack.peek() == '+' || operatorStack.peek() == '-' || operatorStack.peek() == '*' || operatorStack.peek() == '/' )){
                    //如果是之前别的+- 需要弹栈计算
                    processAnOperator(numberStack,operatorStack);
                }
                //入股操作符栈为空 或不为空但栈顶为(
                operatorStack.push(token.charAt(0));
                //遍历 */
            }else if(token.equals("*") || token.equals("/")){
                while (!operatorStack.isEmpty() && (operatorStack.peek() == '*' || operatorStack.peek() == '/' )){
                    //如果是之前别的*/ 需要弹栈计算
                    processAnOperator(numberStack,operatorStack);
                }
                //入股操作符栈为空 或不为空但栈顶为(
                operatorStack.push(token.charAt(0));
                //遍历(
        }else if(token.equals("(")){
                operatorStack.push(token.charAt(0));
                //遍历到)
            }else if(token.equals(")")){
                //操作符栈不是( 全部弹栈计算
                while (operatorStack.peek() != '('){
                    processAnOperator(numberStack,operatorStack);
                }
                //去掉左括号
                operatorStack.pop();
                //遍历到数字
            }else{
                numberStack.push(new Integer(token));
            }
        }
        //处理最后操作符
        while (!operatorStack.isEmpty()){
            processAnOperator(numberStack,operatorStack);
        }
        return numberStack.pop();
    }
    //操作符栈第一个元素 数字栈弹栈两个数字 计算 并入栈数字栈
    private static void processAnOperator(ArrayStack<Integer> numberStack, ArrayStack<Character> operatorStack) {
        char op = operatorStack.pop();
        int num1 = numberStack.pop();
        int num2 = numberStack.pop();
        //num2 op num1
        if(op == '+'){
            numberStack.push(num2 + num1);
        }else if(op == '-'){
            numberStack.push(num2 - num1);
        }else if(op == '*'){
            numberStack.push(num2 * num1);
        }else{
            numberStack.push(num2 / num1);
        }
    }

    //对原表格式化处理 给非数字加空格;
    private static String insertBlanks(String expression) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
                sb.append(' ');
                sb.append(c);
                sb.append(' ');
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

十进制转十六进制

package p2.线性结构;

public class DecToHex {
    public static void main(String[] args) {
        int num = 654321;
        ArrayStack<String> stack = new ArrayStack<>();
        while (num != 0){
            int a = num % 16;
            if (a < 10){
                stack.push(a + "");
            }else {
                stack.push((char)(a + 55) + "");
            }
            num /= 16;
        }
        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()){
            sb.append(stack.pop());
        }
        System.out.println(sb.toString());
    }
}

十六进制转十进制

package p2.线性结构;

public class HexToDec {
    public static void main(String[] args) {
        String hex = "9FBF1";
        ArrayStack<Character> stack = new ArrayStack<>();
        for (int i = 0; i < hex.length();i++){
            stack.push(hex.charAt(i));
        }
        int sum = 0;
        int mi = 0;
        while (!stack.isEmpty()){
            char c = stack.pop();
            sum += getNumber(c) * Math.pow(16,mi);
            mi++;
        }
        System.out.println(sum);
    }

    private static int getNumber(char c) {
        if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F')){
            throw new IllegalArgumentException("wrong char");
        }
        if (c >= '0' && c <= '9'){
            return c - '0';
        }else {
            return c - 'A' + 10;
        }
    }
}

回文判断

package p2.线性结构;
//判断回文
public class JudgingPalindrome {
    public static void main(String[] args) {

        solution01();
        System.out.println(solution02());
    }

    private static boolean solution02() {
        String text = "上海自来水来自海上";
        int i =0;
        int j = text.length() - 1;
        while (true){
            if(text.charAt(i) == text.charAt(j)){
                i++;
                j--;
            }else {
                return false;
            }
            if (j <= i){
                return true;
            }
        }

    }

    private static void solution01() {
        String text = "上海自来水来自海上";
        ArrayStack<Character> stack = new ArrayStack<>();
        for (int i = 0;i < text.length();i++){
            if (text.length()%2 == 1 && i == text.length()/2){
                continue;
            }
            char c = text.charAt(i);
            if (stack.isEmpty()){
                stack.push(c);
            }else {
                if (c != stack.peek()){
                    stack.push(c);
                }else {
                    stack.pop();
                }
            }
        }
        System.out.println(stack.isEmpty());
    }
}

括号匹配

package p2.线性结构;

import java.util.HashMap;

//括号匹配
public class MatchBracket {
    public static void main(String[] args) {
        solution01();
        solution02();
    }

    private static void solution02() {
        String str = "{()[[()]]<>{}()<>}";
        HashMap<Character,Character> map = new HashMap<>();
        map.put('[',']');
        map.put('<','>');
        map.put('(',')');
        map.put('{','}');
        ArrayStack<Character> stack = new ArrayStack<>();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (stack.isEmpty()) {
                stack.push(c);
            } else {
                char top = stack.peek();
                if (map.containsKey(top) && c == map.get(']')) {
                    stack.pop();
                } else {
                    stack.push(c);
                }
            }
        }
        System.out.println(stack.isEmpty());
    }

    private static void solution01() {
        String str = "{()[[()]]<>{}()<>}";
        ArrayStack<Character> stack = new ArrayStack<>();
        for (int i = 0; i < str.length();i++){
            char c = str.charAt(i);
            if (stack.isEmpty()){
                stack.push(c);
            }else {
                char top = stack.peek();
                if (top - c == -1 || top - c == -2){
                    stack.pop();
                }else {
                    stack.push(c);
                }
            }
        }
        System.out.println(stack.isEmpty());
    }
}

双端栈

在一个线性表的两端做栈底分别进行入栈和出栈操作

主要利用栈 栈底位置不变,栈顶位置动态变化 特性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggWcrHJu-1642155306472)(C:\Users\qwe123\AppData\Roaming\Typora\typora-user-images\image-20220113092736512.png)]

双端站是线性表的一种 栈的一个特殊分类

用动态数组实现双端栈

package p2.线性结构;
//双端栈
import java.util.Arrays;
import java.util.Iterator;

public class ArrayDoubleEndStack<E> implements Iterable<E> {
    //左端栈顶
    private int ltop;
    //右端栈顶
    private int rtop;
    //存储元素容器
    private E[] data;
    //数组容器默认容量
    private static int DEFAULT_CAPACITY = 10;

    public ArrayDoubleEndStack(){
        data = (E[]) new Object[DEFAULT_CAPACITY];
        ltop = -1;
        rtop = data.length;
    }
    //进栈
    public void pushLeft(E element){
        if (ltop + 1 == rtop){
            resize(data.length * 2);
        }
        data[++ltop] = element;
    }

    public void pushRlght(E element){
        if (ltop + 1 == rtop){
            resize(data.length * 2);
        }
        data[--rtop] = element;
    }
    //resize 扩容 缩容
    private void resize(int newLen) {
        E[] newData = (E[]) new Object[newLen];
        //复制左端元素
        for (int i = 0;i <= ltop;i++){
            newData[i] = data[i];
        }
        //复制右端元素
        int index = rtop;
        for (int i = newLen - sizeRight(); i < newLen;i++){
            newData[i] = data[index++];
        }
        rtop = newLen - sizeRight();
        data = newData;
    }
    //出栈
    public E popLeft(){
        if (isLeftEmpty()){
            throw new IllegalArgumentException("Left null");
        }
        E ret =  data[ltop--];
        if (sizeLeft() + sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY){
            resize(data.length / 2);
        }
        return ret;
    }

    public E popRight(){
        if (isRightEmpty()){
            throw new IllegalArgumentException("Right null");
        }
        E ret = data[rtop++];
        if (sizeLeft() + sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY){
            resize(data.length / 2);
        }
        return ret;
    }

    //栈顶
    public E peekLeft(){
        if (isLeftEmpty()){
            throw new IllegalArgumentException("Left null");
        }
        return data[ltop];
    }

    public E peekRight(){
        if (isRightEmpty()){
            throw new IllegalArgumentException("Right null");
        }
        return data[rtop];
    }


    public boolean isLeftEmpty(){
        return ltop == -1;
    }

    public boolean isRightEmpty(){
        return rtop == data.length;
    }

    public int sizeLeft(){
        return ltop + 1;
    }

    public int sizeRight(){
        return data.length - rtop;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isLeftEmpty() && isRightEmpty()){
            sb.append(']');
            return sb.toString();
        }

        //左右都不空  先左
        for (int i = 0;i <= ltop;i++){
            sb.append(data[i]);
            if (i == ltop && isRightEmpty()){
                sb.append(']');
                return sb.toString();
            }else {
                sb.append(',');
            }
        }
        //右边
        for (int i = rtop; i < data.length;i++){
            sb.append(data[i]);
            if (i == data.length - 1){
                sb.append(']');
            }else {
                sb.append(',');
            }
        }
        return sb.toString();
    }

    @Override
    public Iterator<E> iterator() {
        return new ArrayDoubleEndStackIterator();
    }
    class ArrayDoubleEndStackIterator implements Iterator<E>{

        private ArrayList<E> list;
        private Iterator<E> it;
        public ArrayDoubleEndStackIterator(){
            list = new ArrayList<>();
            for (int i = 0;i <= ltop;i++){
                list.add(data[i]);
            }
            for (int i = rtop;i < data.length;i++){
                list.add(data[i]);
            }
            it = list.iterator();
        }

        @Override
        public boolean hasNext() {
            return it.hasNext();
        }

        @Override
        public E next() {
            return it.next();
        }
    }

}

package p0.测试;

import p2.线性结构.ArrayDoubleEndStack;

public class TestArrayDoubleEndStack {
    public static void main(String[] args) {
        ArrayDoubleEndStack<Integer> stack01 = new ArrayDoubleEndStack<>();
        System.out.println(stack01);
        for (int i = 0; i < 10;i++){
            stack01.pushLeft(i);
        }
        System.out.println(stack01);

        ArrayDoubleEndStack<Integer> stack02 = new ArrayDoubleEndStack<>();
        System.out.println(stack02);
        for (int i = 0; i < 10;i++){
            stack02.pushRlght(i);
        }
        System.out.println(stack02);

        ArrayDoubleEndStack<Integer> stack03 = new ArrayDoubleEndStack<>();
        System.out.println(stack03);
        for (int i = 0; i < 10;i++){
            stack03.pushLeft(i);
            stack03.pushRlght(i);

        }
        System.out.println(stack03);

        for (Integer num: stack03) {
            System.out.println(num);
        }
    }
}

队列

只允许在一端插入 在另一端删除的线性表

删除的一端叫队首 插入的一端叫队尾

不含任何元素叫空队列 先进先出

插入叫入队 删除叫出队

package p1.接口;

public interface Queue<E> extends Iterable<E> {
    //入队
    public void offer(E element);
    //出队
    public E poll();
    //查看队首元素
    public E peek();
    public boolean isEmpty();
    public void clear();
    public int size();

}

package p2.线性结构;

import p1.接口.Queue;

import java.util.Iterator;
import java.util.Objects;

public class ArrayQueue<E> implements Queue<E> {
    private  ArrayList<E> list;
    public ArrayQueue(){
        list = new ArrayList<>();
    }

    @Override
    public void offer(E element) {
        list.add(list.size(),element);
    }

    @Override
    public E poll() {
        return list.remove(0);
    }

    @Override
    public E peek() {
        return list.get(0);
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }

    @Override
    public String toString() {
        return list.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (o == null){
            return false;
        }
        if (this == o){
            return true;
        }
        if (o instanceof ArrayQueue){
            ArrayQueue other = (ArrayQueue) o;
            return list.equals(other.list);
        }
        return false;
    }


}

package p0.测试;

import p2.线性结构.ArrayQueue;

public class TestArrayQueue {
    public static void main(String[] args) {
        ArrayQueue<Integer> queue = new ArrayQueue<>();
        for (int i = 1; i <= 10;i++){
            queue.offer(i);
        }
        System.out.println(queue);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue);
    }
}

文件夹遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x09yaGJZ-1642155306474)(C:\Users\qwe123\AppData\Roaming\Typora\typora-user-images\image-20220113112803447.png)]

package p2.线性结构;

import java.io.File;

//文件夹遍历
public class DirectoryTraversal {
    public static void main(String[] args) {
         /*
        只要队列不为空 出一个目录对象
        将该目录对象展开 遍历 遇到文件打印名称 遇到其他目录进队
         */
        File dir = new File("C:\\Users\\qwe123\\Documents\\WeChat Files\\wxid_0674puy2lnqz21\\FileStorage\\File\\2022-01\\Day04\\DS");
        ArrayQueue<File> queue = new ArrayQueue<>();
        queue.offer(dir);
        while (!queue.isEmpty()){
            File file = queue.poll();
            System.out.println("【"+ file.getName() + "】");
            File[] files = file.listFiles();
            for (File f : files){
                if (f.isFile()){
                    System.out.println(f.getName());
                }else {
                    queue.offer(f);
                }
            }
        }
    }
}

栈实现队列

package p2.线性结构;

import p1.接口.Queue;

import java.util.Iterator;

//栈实现队列
public class StackToQueue {
    public static void main(String[] args) {
        QueueImpByStack<Integer> queue = new QueueImpByStack<>();
        for (int i = 1;i <= 5 ;i++){
            queue.offer(i);
        }
        System.out.println(queue);
        System.out.println(queue.poll());
        System.out.println(queue);
    }
}
    class QueueImpByStack<E> implements Queue<E> {
        private ArrayStack<E> stackA;
        private ArrayStack<E> stackB;
        public QueueImpByStack(){
            stackA = new ArrayStack<>();
            stackB = new ArrayStack<>();
        }

        @Override
        public void offer(E element) {
            stackA.push(element);
        }

        @Override
        public E poll() {
            if (isEmpty()){
                throw new IllegalArgumentException("queue null");
            }
            while (stackA.size() != 1){
                stackB.push(stackA.pop());
            }
            E ret = stackA.pop();
            while (!stackB.isEmpty()){
                stackA.push(stackB.pop());
            }
            return ret;
        }

        @Override
        public E peek() {
            if (isEmpty()){
                throw new IllegalArgumentException("queue null");
            }
            while (stackA.size() != 1){
                stackB.push(stackA.pop());
            }
            E ret = stackA.peek();
            while (!stackB.isEmpty()){
                stackA.push(stackB.pop());
            }
            return ret;
        }

        @Override
        public boolean isEmpty() {
            return stackA.isEmpty();
        }

        @Override
        public void clear() {
            stackA.clear();
        }

        @Override
        public int size() {
            return stackA.size();
        }

        @Override
        public Iterator<E> iterator() {
            return null;
        }

        @Override
        public String toString() {
            return stackA.toString();
        }
    }


队列实现栈

package p2.线性结构;

import p1.接口.Stack;

import java.util.Iterator;

//队列实现栈
public class QueueToStack {
    public static void main(String[] args) {
        StackImplByQueue<Integer> stack = new StackImplByQueue<>();
        System.out.println(stack);
        for (int i = 1; i <= 5; i++) {
            stack.push(i); //队列A
        }
        System.out.println(stack.toString());
        System.out.println(stack.pop());
        System.out.println(stack);  //队列B

    }
}
class StackImplByQueue<E> implements Stack<E> {
    private ArrayQueue<E> queueA;
    private ArrayQueue<E> queueB;

    public StackImplByQueue() {
        queueA = new ArrayQueue<>();
        queueB = new ArrayQueue<>();
    }

    @Override
    public int size() {
        if (queueA.isEmpty() && queueB.isEmpty()) {
            return 0;
        } else if (!queueA.isEmpty()) {
            return queueA.size();
        } else {
            return queueB.size();
        }
    }

    @Override
    public boolean isEmpty() {
        return queueA.isEmpty() && queueB.isEmpty();
    }

    @Override
    public void push(E element) {
        if (queueA.isEmpty() && queueB.isEmpty()) {
            queueA.offer(element);
        } else if (!queueA.isEmpty()) {
            queueA.offer(element);
        } else {
            queueB.offer(element);
        }
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            return null;
        }
        E ret = null;
        if (!queueA.isEmpty()) {
            while (queueA.size() != 1) {
                queueB.offer(queueA.poll());
            }
            ret = queueA.poll();
        } else {
            while (queueB.size() != 1) {
                queueA.offer(queueB.poll());
            }
            ret = queueB.poll();
        }
        return ret;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        E ret = null;
        if (!queueA.isEmpty()) {
            while (queueA.size() != 1) {
                queueB.offer(queueA.poll());
            }
            ret = queueA.poll();
            queueB.offer(ret);
        } else {
            while (queueB.size() != 1) {
                queueA.offer(queueB.poll());
            }
            ret = queueB.poll();
            queueA.offer(ret);
        }
        return ret;
    }

    @Override
    public void clear() {
        queueA.clear();
        queueB.clear();
    }

    @Override
    public Iterator<E> iterator() {
        if (isEmpty()) {
            return queueA.iterator();
        } else if (!queueA.isEmpty()) {
            return queueA.iterator();
        } else {
            return queueB.iterator();
        }
    }
    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        } else if (!queueA.isEmpty()) {
            return queueA.toString();
        } else {
            return queueB.toString();
        }
    }

}

回顾Array Queue

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5p5oZUhv-1642155306476)(C:\Users\qwe123\AppData\Roaming\Typora\typora-user-images\image-20220113191529649.png)]

循环队列ArrayLoopQueue

该循环队列的实现思想是动态数组

package p2.线性结构;

import p1.接口.Queue;

import java.io.SequenceInputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;

//循环队列
public class ArrayLoopQueue implements Queue {
//存储数据容器
private E[] data;
//对首指针
private int front;
//队尾指针
private int rear;
//元素个数(f<r r-F ; r<f r+L-f)
private int size;
//默认容量
private static int DEFAULT_CAPACITY = 10;

​ public ArrayLoopQueue(){
​ data = (E[]) new Object[DEFAULT_CAPACITY + 1];
​ front = 0;
​ rear = 0;
​ size = 0;
​ }

​ @Override
​ public void offer(E element) {
​ if ((rear + 1) % data.length == front){
​ resize(data.length * 2 - 1);
​ }
​ data[rear] = element;
​ rear = (rear + 1) % data.length;
​ size++;
​ }

​ @Override
​ public E poll() {
​ if (isEmpty()){
​ throw new IllegalArgumentException(“queue null”);
​ }
​ E ret = data[front];
​ front = (front + 1) % data.length;
​ size–;
​ if(size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY){
​ resize(data.length / 2 +1);
​ }
​ return ret;
​ }

​ private void resize(int newLen) {
​ E[] newData = (E[]) new Object[newLen];
​ int index = 0;
​ for (int i = front; i != rear;i = (i + 1) % data.length){
​ newData[index++] = data[i];
​ }
​ data = newData;
​ front = 0;
​ rear = index;
​ }

​ @Override
​ public E peek() {
​ if (isEmpty()){
​ throw new IllegalArgumentException(“queue null”);
​ }
​ return data[front];
​ }

​ @Override
​ public boolean isEmpty() {
​ return front == rear;
​ }

​ @Override
​ public void clear() {
​ data = (E[]) new Object[DEFAULT_CAPACITY];
​ size = 0;
​ front = 0;
​ rear = 0;
​ }

​ @Override
​ public int size() {
​ return size;
​ }

​ @Override
​ public String toString() {
​ StringBuilder sb = new StringBuilder();
​ sb.append(’[’);
​ if (isEmpty()){
​ sb.append(’]’);
​ return sb.toString();
​ }
​ for (int i = front; i != rear ; i = (i + 1) % data.length){
​ sb.append(data[i]);
​ if ((i + 1 % data.length == rear)){
​ sb.append(’]’);
​ }else {
​ sb.append(’,’);
​ sb.append(’ ');
​ }
​ }
​ return sb.toString();
​ }

​ @Override
​ public boolean equals(Object o) {
​ if (o == null){
​ return false;
​ }
​ if (this == o){
​ return true;
​ }
​ if (o instanceof ArrayLoopQueue){
​ ArrayLoopQueue other = (ArrayLoopQueue) o;
​ if (size != other.size){
​ return false;
​ }
​ int i = front;
​ int j = other.front;
​ while (i != rear){
​ if (data[i].equals(other.data[j])){
​ return false;
​ }
​ i = (i + 1) % data.length;
​ j = (j + 1) % other.data.length;
​ }
​ return true;
​ }
​ return false;
​ }

​ @Override
​ public Iterator iterator() {
​ return null;
​ }
​ class ArrLoopQueueIterator implements Iterator{
​ private int cur = front;
​ @Override
​ public boolean hasNext() {
​ return cur != rear;
​ }

​ @Override
​ public E next() {
​ E ret = data[cur];
​ cur = (cur + 1) % data.length;
​ return ret;
​ }
​ }
}

package p2.线性结构;

import java.io.File;

//文件夹遍历
public class DirectoryTraversal {
    public static void main(String[] args) {
         /*
        只要队列不为空 出一个目录对象
        将该目录对象展开 遍历 遇到文件打印名称 遇到其他目录进队
         */
        File dir = new File("C:\\Users\\qwe123\\Documents\\WeChat Files\\wxid_0674puy2lnqz21\\FileStorage\\File\\2022-01\\Day04\\DS");
        ArrayLoopQueue<File> queue = new ArrayLoopQueue<>();
        queue.offer(dir);
        while (!queue.isEmpty()){
            File file = queue.poll();
            System.out.println("【"+ file.getName() + "】");
            File[] files = file.listFiles();
            for (File f : files){
                if (f.isFile()){
                    System.out.println(f.getName());
                }else {
                    queue.offer(f);
                }
            }
        }
    }
}

双端队列

限定插入和删除操作在表两端的线性表

是具有队列和栈的性质的数据结构

package p1.接口;

public interface Dequeue<E> extends Queue<E> {
    public void addFirst(E element);
    public void addLast(E element);
    public E removeFirst();
    public E reomveLast();
    public E getFirst();
    public E getLast();
}
package p2.线性结构;

import p1.接口.Dequeue;
import p1.接口.Stack;

import java.util.Arrays;
import java.util.Iterator;

public class ArrayDeque<E> implements Dequeue<E>, Stack<E> {
    private E[] data;
    private int front;
    private int rear;
    private int size;
    private static int DEFAULT_CAPACITY = 10;

    public ArrayDeque() {
        data = (E[]) new Object[DEFAULT_CAPACITY + 1];
        front = 0;
        rear = 0;
        size = 0;
    }

    @Override
    public void addFirst(E element) {
        if ((rear + 1) % data.length == front) {
            resize(data.length * 2 - 1);
        }
        front = (front - 1 + data.length) % data.length;
        data[front] = element;
        size++;
    }

    private void resize(int newLen) {
        E[] newData = (E[]) new Object[newLen];
        int index = 0;
        for (int i = front; i != rear; i = (i + 1) % data.length) {
            newData[index++] = data[i];
        }
        data = newData;
        front = 0;
        rear = index;
    }

    @Override
    public void addLast(E element) {
        if ((rear + 1) % data.length == front) {
            resize(data.length * 2 - 1);
        }
        data[rear] = element;
        rear = (rear + 1) % data.length;
        size++;
    }

    @Override
    public E removeFirst() {
        if (isEmpty()) {
            throw new IllegalArgumentException("queue is null");
        }
        E ret = data[front];
        front = (front + 1) % data.length;
        size--;
        if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
            resize(data.length / 2 + 1);
        }
        return null;
    }

    @Override
    public E reomveLast() {
        if (isEmpty()) {
            throw new IllegalArgumentException("queue is null");
        }
        rear = (rear - 1 + data.length) % data.length;
        E ret = data[rear];
        size--;
        if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
            resize(data.length / 2 + 1);
        }
        return ret;
    }

    @Override
    public E getFirst() {
        if (isEmpty()) {
            throw new IllegalArgumentException("queue is null");
        }
        return data[front];
    }

    @Override
    public E getLast() {
        if (isEmpty()) {
            throw new IllegalArgumentException("queue is null");
        }
        return data[(rear - 1 + data.length) % data.length];
    }

    @Override
    public void offer(E element) {
        addLast(element);
    }

    @Override
    public E poll() {
        return removeFirst();
    }

    @Override
    public E element() {
        return getFirst();
    }

    @Override
    public E peek() {
        return getLast();
    }

    @Override
    public boolean isEmpty() {
        return size == 0 && front == rear;
    }

    @Override
    public void push(E element) {
        addLast(element);
    }

    @Override
    public E pop() {
        return reomveLast();
    }

    @Override
    public void clear() {
        E[] data = (E[]) new Object[DEFAULT_CAPACITY];
        front = 0;
        rear = 0;
        size = 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()) {
            sb.append(']');
            return sb.toString();
        }
        for (int i = front; i != rear; i = (i + 1) % data.length) {
            sb.append(data[i]);
            if ((i + 1) % data.length == rear) {
                sb.append(']');
            } else {
                sb.append(',');
                sb.append(' ');
            }
        }
        return sb.toString();
    }

    @Override
    public Iterator<E> iterator() {
        return new ArrayDequeIterator();
    }

    class ArrayDequeIterator implements Iterator<E> {
        private int cur = front;

        @Override
        public boolean hasNext() {
            return cur != rear;
        }

        @Override
        public E next() {
            E ret = data[cur];
            cur = (cur + 1) % data.length;
            return ret;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值