算法和数据结构

了解数据

数据们之间的关系——逻辑结构

线性结构:元素是一对一关系
树形结构:元素之间存在一对多的层次关系
图形结构:元素存在多对多关系

关系在计算机上的存储——物理结构

顺序存储结构:开辟一组连续的空间存储数据
链式存储结构:开辟一组随机的空间存储数据
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
其中:树形结构方便查找,但是存在预留空间
而图形结构的虽然没有预留空间,但是不方便查

算法

定义是解决特地问题求解步骤的描述

算法的时间复杂度

1.常数阶O(1)
2.线性阶O(n)
3.平方阶O ( n^2)
4.对数阶(log^n)
在这里插入图片描述

动态数组与静态数组

java内置数组的缺点

长度不可变,容量不够
角标访问快,增删元素
数组只有length属性
java内置数组的特点
数组的长度一旦确定,不能进行改变
数组只能存储同一类型的数据
数组中每个存储空间地址是连续且相等的
数组提供角标的·方式访问元素

Arraylist

1.创建LIst接口并使用泛型兼容各种数据类型
提供大量方法

public interface List<E> extends Iterable<E>{
    //默认在表尾添加一个元素
    public void add(E element);
    //在指定角标处添加元素
    public void add(int index,E element);
    //删除指定元素
    public void remove(E element);
    //删除指定角标处的元素,并返回原先的值
    public E remove(int index);
    //获取指定角标处的元素
    public E get (int index);
    //修改指定角标index处的值为element 并返回原先的值
    public E set (int index,E element);
    //获取线性表中的元素个数
    public int size();
    //查看元素第一次中的角标位置(从左到右)
    public int indexof(E element);
    //判断是否包含元素
    public boolean contains(E element);
    //判断线性表是否为空
    public Boolean isEmpty();
    //清空线性表
    public void clear();
    //按照比较器的内容进行排序
    public void sort(Comparator<E> c);
    //获取子线性表 原线性表中【fromIndex, toindex】这个部分
    public List<E> subList(int fromIndex, int toIndex);
}

在arrayLIst中继承接口List并且将方法具体化

package p2;

import p1.List;


import java.util.Comparator;
import java.util.Iterator;


public class ArrayList<E> implements List<E> {
    //数组的容器
    private E[] data;

    //元素的个数 size==0 表示线性表为空 ,size==data.length 表示线性表满了
    //size新元素默认尾部添加时要去的角标
    private int size;

    //默认容量
    private static int DEFAULT_CAPACITY = 10;
    //默认构造函数:创建一个默认容量为10的线性表
    public ArrayList() {
        data = (E[]) new Object[DEFAULT_CAPACITY];
        size =0;
    }
    //指定默认容量的构造函数:创建一个指定容量的线性表
    public ArrayList(int capacity){
        if (capacity<=0){
            throw new IllegalArgumentException("capacity must>8");
        }
        DEFAULT_CAPACITY = capacity;
        data = (E[]) new Object[DEFAULT_CAPACITY];
        size=0;
    }
    //指定数组的构造函数:传入一个数组 将该数组封装成为一个线性表
    public ArrayList(E[] arr){
        if (arr ==null || arr.length==0) {
            throw new IllegalArgumentException("arr can not bo null");
        }
        data = (E[]) new Object[DEFAULT_CAPACITY];
            for (int i = 0; i < arr.length; i++) {
                add(arr[i]);
            }

        }





    @Override
    public void add(E element) {
        add(size,element);

    }

    @Override
    public void add(int index, E element) {
        if (index<0||index >size){
            throw  new IllegalArgumentException("can not add");
            
        }
        //判断线性表是否是满状态,需不需要进行扩容
        if (size==data.length){
            resize(2*data.length);
        }
//        向后移动元素
        for (int i = size-1; i >=index ; i--) {
            data[i+1] = data[i];
        }
        //添加元素
        data[index]=element;
        size++;
    }
//    扩容/缩容
    private void resize(int newLength) {

        E[] newData= (E[]) new Object[newLength];
        for (int i = 0; i < size; i++) {
            newData[i] = data[i];
        }
        data = newData;
    }

    @Override
    public void remove(E element) {//删除指定元素 只删除一次&&删除所有数据
        int index = indexof(element);
          if(index!=-1){
              remove(index);
          }
    }

    @Override
    public E remove(int index) {
        if (index<0||index>=size){
            throw new IllegalArgumentException("remove index out of range");

        }


        //先保存要的值
        E ret = data[index];

        for (int i = index+1; i < size; i++) {
            data[i-1]=data[i];
        }
        size--;
        /*什么时候缩容
        有效元素是容量的1/4我们将元素变成容量的1/2
        当前的容量的不能低于默认设置的容量*/

        if (size== data.length/4 && data.length >DEFAULT_CAPACITY){
            resize(data.length/2);
        }
        //返回值
        return ret;
    }

    @Override
    public E get(int index) {
        if (index<0||index>=size){
            throw new IllegalArgumentException("get index out of range");
        }
        return data[index];
    }

    @Override
    public E set(int index, E element) {
        if (index<0||index>=size){
            throw new IllegalArgumentException("get index out of range");
        }
        E ret= data[index];/*先把数据拿出来,这样这个数据所在的角标就空了*/
        data[index]= element;
        return ret;
    }

    @Override
    public int size() {
        return size;
    }
    //额外添加一个函数 获取线性表中那个数组的容量
    private int getCapacity(){
        return data.length;
    }

    @Override
    public int indexof(E element) {
        /*
        == 俩边是数据类型的时候比的是值
        == 俩边是引用数据类型的时候比的是地址*/
        for (int i = 0; i < size; i++) {
            if (data[i]==element){
                return i;
            }
        }
        return -1;
    }

    @Override
    public boolean contains(E element) {
        return false;
    }

    @Override
    public Boolean isEmpty() {
        return size==0;
    }

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

    @Override
    public void sort(Comparator<E> c) {
        if (c==null){
            throw new IllegalArgumentException("compare can not be null");
        }
        for (int i = 0; i < size; i++) {
            E e=data[i];
            int j=0;
            for ( j = i; j >0 && c.compare(data[j-1],e )>0 ; j++) {/*data[j-1]>e*/
                data[j]=data[j-1];
            }
            data[j]=e;
        }
    }

    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        if (fromIndex<0||toIndex>=size||fromIndex>toIndex){
            throw new IllegalArgumentException("must 0");
        }
        ArrayList<E>List = new ArrayList<>();
        for (int i = fromIndex; i <=toIndex ; i++) {
            List.add(data[i]);
        }
        return List;
    }

    @Override
    public boolean equals(Object o) {
        //1.判空
        if (o ==null){
            return false;
        }
        //2.判自己
        if (this==o){
            return false;
        }
        //3.判类型
        if (o instanceof ArrayList){
            //4.按照自己的逻辑进行比较
            ArrayList<E> other = (ArrayList<E>) o;
            //5.先比较有效元素的个数
            if (size!= other.size){
                return false;
            }
            //6.有效元素个数相等的情况下 逐个比较元素
            for (int i = 0; i < size; i++) {
                if (!data[i].equals(other.data[i])){
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
       StringBuilder sb= new StringBuilder();
       sb.append('[');
       if (isEmpty()){
           sb.append(']');

       }else {
           for (int i = 0; i <size ; i++) {
               sb.append(data[i]);
               if (i==size-1){
                   sb.append(']');
               }else {
                   sb.append(',');
                   sb.append(' ');
               }
           }
       }
       return sb.toString();
    }
//获取当前数据结构?容器的迭代器
    //通过迭代器 更方便挨个取出每个元素
    //同时实现了Iterator 可以让当前的数据结构/容器 被foreach循环使用
    @Override
    public Iterator<E> iterator() {
        return null;
    }

//创建一个属于ArrayList的迭代器
    class ArrayListIterator implements Iterator<E>{
        private int cur = 0;
    @Override
    public boolean hasNext() {
        return cur<size;
    }

    @Override
    public E next() {
        return data[cur++];
    }
}
}

arraystack

在这里插入图片描述
Arraystack继承了部分ArrayList部分功能 ,并且进行了个性化(实现了自己独有的功能)
代码:`package p2;

/只是借用了部分ArrayList部分方法/
import p1.Stack;

import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;

public class ArrayStack implements Stack {
private ArrayListList;
public ArrayStack(){
List = new ArrayList<>();
}
public ArrayStack(int capacity){
List = new ArrayList<>(capacity);
}
//获取当前元素中的有效个数
@Override
public int size() {
return List.size();
}

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

@Override
public void push(E element) {
    List.add(element);
}

@Override
public E pop() {
    return List.remove(List.size()-1);
}

@Override
public E peek() {
    return List.get(List.size()-1);
}

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

@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 ArrayStack){
        ArrayStack other = (ArrayStack) o;/*强行转换*/
        return this.List.equals(other.List);
    }
    return false;
}

@Override
public int hashCode() {
    return List != null ? List.hashCode() : 0;
}

@Override
public void forEach(Consumer<? super E> action) {
    Stack.super.forEach(action);
}

@Override
public Spliterator<E> spliterator() {
    return Stack.super.spliterator();
}

}
`

栈是限定仅在表尾进行插入和删除操作的线性表
(ArrayList可以在任意位置进行数据操作)
1.我们把允许插入和删除的一端称为栈顶(top),另一端称为为栈底
2.不含任何数据元素的栈称为空栈
3.栈又称为后进先出的线性表
4.栈本身是一个线性表,其数据元素具有线性关系,只不过它是一种特殊的线性表而已
5.栈的插入操作,叫做进栈
6.栈的删除操作,叫做出栈

中缀表达式

1.是一个通用的算术或逻辑公式表示方法,操作符是以中缀形式处于操作数的中间(列:3+4)
2.与前缀表达式和后缀表达式相比,中缀表达式不容易被计算机解析,但是仍然被许多程序语言使用
3.中缀记法中括号是必要的

栈是如何实现中缀表达式的

在这里插入图片描述
operatorStack:是操作使用符号栈
numberStack: 是数字存放栈
运算法则:根据入栈operatorStack的操作符的优先级来判断运算的,同等级优先运算前者,高等级的运算后者
(只有发生同等级,或者前者的等级高于后者的等级的时候进行运算)
案例效果展示:
在这里插入图片描述
代码实现:

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) {   //token == tokens[i]
            //过滤空串
            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) {
        /* (10+20/2*3)/2+8
         */   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();
    }
}

双端栈

是指将一个线性表的俩段当作栈底分别进行入栈和出栈操作
在这里插入图片描述
双端栈的实现:ArrayDoubleEndstack
代码实现:

package p2;

import p1.Stack;

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

/*双端栈
* Iterable实现可遍历*/
public class ArrayDoubleEndStack<E>implements Iterable<E> {
//左端栈的栈顶
    private int ltop;
    //右端栈的栈顶
    private int rtop;
    //存储元素的容器
    private E[]data;
    //数组容量的默认值
    private static int DEFAUIT_CAPACITY = 10;

    public ArrayDoubleEndStack() {
        data = (E[]) new Object[DEFAUIT_CAPACITY];
        ltop = -1;
        rtop = data.length;
    }
public void pushLeft(E element){
        if (ltop+1==rtop){
            resize(data.length*2);
        }
        data[++ltop]=element;
}
    public void pushRight(E element){
        if (ltop+1==rtop){
            resize(data.length*2);
        }
        data[--rtop]=element;
    }
//    扩容/缩容
    private void resize(int newLength) {

        E[] newData= (E[]) new Object[newLength];
       //复制左端栈的元素
        for (int i = 0; i <=ltop ; i++) {
           newData[i] = data[i];
        }
        //复制右端栈的元素
        int index= rtop;
      for (int i= newLength-sizeRight();i<newLength;i++){
          newData[i] = data[index++];
      }
      rtop = newLength-sizeRight();
        data = newData;
    }
    /*出栈*/
    public E popLeft(){
        if (isLeftEmpty()){
            throw  new IllegalArgumentException("left stack is null");
        }
        E ret =data[ltop--];
        if (sizeLeft()+sizeRight()<=data.length/4&&data.length>DEFAUIT_CAPACITY){
            resize(data.length/2);
        }
        return ret;

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

    }
    /*查看栈顶*/
    public E peekLeft(){
        if (isLeftEmpty()){
            throw new IllegalArgumentException("left stack is null");
        }
        return data[ltop];
    }
    public E peekRight(){
        if (isRightEmpty()){
            throw new IllegalArgumentException("left stack is 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 test;

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.pushRight(i);

        }
        System.out.println(stack02);

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

        }
        System.out.println(stack03);
    }

    }


结果展示
在这里插入图片描述

队列

队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表‘

我们把允许删除的一端称为队首,插入的一端称为队尾
不含任何数据元素的队列称为空队列
队列是一种先进后出的线性表,简称FIFO
队列本身是一个线性表,其数据元素具有线性关系,只不过它是一种特殊的线性表而已
队列的插入操作,叫做入队
队列的删除操作,叫做出队

代码实现:

package p2;

import p1.Queue;

import java.util.Iterator;

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

}


循环队列

将普通的队列变成一个循环队列,节省空间,因此需要定义一个头指针和尾指针

需要预留一个位置空给尾指针

假设不留空,那么就会导致判断空或者满的时候判断条件是一样的

因此我们需要留一个位置给尾指针,用来改变判断条件

package p2;

import p1.Queue;


import java.util.Iterator;

public class ArrayLoopQueue<E>implements Queue<E> {
    private E[] data;   //存储数据的容器
    private int front;  //队首指针(实际上就是数组中的索引角标)
    private int rear;   //队尾指针
    private int size;   //元素的个数 (f < r  r-f ; r < f  r+L-f)
    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 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 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;
    }


    public E element() {
        if (isEmpty()) {
            throw new IllegalArgumentException("queue is 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<E> other = (ArrayLoopQueue<E>) 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<E> iterator() {
        return new ArrayLoopQueueIterator();
    }

    class ArrayLoopQueueIterator 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;
        }
    }
}

文件夹遍历

代码:

package p2;

import java.io.File;

/*文件夹遍历*/
public class Directory {
    public static void main(String[] args) {
        File dir =new File("F:\\Flask\\day01");
        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.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("wrong");

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

    @Override
    public E removeLast() {
        if (isEmpty()){
            throw new IllegalArgumentException("wrong");

        }
        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("wrong");

        }
        return data[front];
    }

    @Override
    public E getLast() {
        if (isEmpty()){
            throw new IllegalArgumentException("wrong");

        }
        return data[(rear-1+data.length)%data.length];
    }

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



    @Override
    public E element() {
        return getFirst();
    }
    //栈
    @Override
    public E poll() {
        return removeFirst();
    }
    @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 removeLast();
    }

    @Override
    public void clear() {
E[]data= (E[]) new Object[DEFAULT_CAPACITY];
rear=0;
front=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;
        }
    }
}

链表

定义:在这里插入图片描述

在这里插入图片描述

单向链表

package p3链式结构;

import p1.List;

import java.util.Comparator;
import java.util.Iterator;
//单项链表
public class LinkedSingList<E>implements List<E> {

//定义结点对象
    private class Node{
        E data;
        Node next;
    public  Node(){
        this(null,null);
    }
    public  Node (E data){
        this(data,null);

    }

    public Node (E data, Node next ){
        this.data = data;
        this.next = next;
    }

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

}


    private Node head;
    private Node tail;
    private int size;


 public LinkedSingList(){
        head = null;
        tail = null;
        size=0;
      }
    public LinkedSingList(E[] arr) {
        if (arr == null || arr.length == 0) {
            throw new IllegalArgumentException("arr is null");
        }
        for (int i = 0; i < arr.length; i++) {
            add(arr[i]);
        }
    }


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

    @Override
    public void add(int index, E element) {
          if (index<0||index>size){
              throw  new IllegalArgumentException("wrong");
          }
          //创建元素节点
        Node n = new Node(element) ;

          if (size==0){
              head=n;
              tail=n;
          }else if (index==0){
              n.next = head;
              head = n;
        }else if (index==size){
              tail.next = n;
              tail = n;
          }else {
              Node p =head;
              for (int i = 0; i < index-1; i++) {
                  p = p.next;
              }
              n.next = p.next;
              p.next = n;
          }size++;


    }

    @Override
    public void remove(E element) {
        int index = indexof(element);
        if (index != -1) {
            remove(index);
        }
    }

    @Override
    public E remove(int index) {
     if (index<0||index>=size){
         throw  new IllegalArgumentException("remove out of range");
     }
     E ret=null;
     if (size==1){
       ret = head.data;
       head = null;
       tail =null;
     }else if (index==0){
         Node n = head;
         ret=n.data;
         head=n.next;
         n.next =null;

     }else if (index==size-1){
         Node p =head;
         while (p.next!=tail){
             p=p.next;
         }
         ret = tail.data;
         p.next =null;
         tail =p;
     }else {
       Node p =head;
         for (int i = 0; i < index-1; i++) {
                 p=p.next;
         }
         Node n =p.next;
         ret = n.data;
         p.next = n.next;
         n.next = null;
     }
        size--;
        return ret;
    }

    @Override
    public E get(int index) {
        if (index<0||index>=size){
            throw  new IllegalArgumentException("get out of range");
        }

        if (index==0){
            return head.data;
        }else if (index==size-1){
            return tail.data;
        }else {
            Node p  =head;
            for (int i = 0; i < index; i++) {
                p = p.next;
            }
            return p.data;
        }

    }

    @Override
    public E set(int index, E element) {
        if (index<0||index>=size){
            throw  new IllegalArgumentException("get out of range");
        }
        E ret=null;
        if (index==0){
            ret =  head.data;

        }else if (index==size-1){
            return tail.data;
        }else {
            Node p  =head;
            for (int i = 0; i < index; i++) {
                p = p.next;
            }
            ret = p.data;
            p.data = element;
        }
 return ret;
    }

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

    @Override
    public int indexof(E element) {
     Node p =head;
     int index = 0;
     while (!p.data.equals(element)){
         p = p.next;
         index++;
         if (p==null){
             return -1;
         }
     }
        return index;
    }

    @Override
    public boolean contains(E element) {
        return indexof(element) != -1;
    }

    @Override
    public boolean isEmpty() {
        return size==0&&head ==null&&tail==null;
    }

    @Override
    public void clear() {
         head = null;
         size = 0;
         tail =null;
    }

    @Override
    public void sort(Comparator<E> c) {
      if (c==null) {
          throw new IllegalArgumentException("wrong");
      }
//          //插入排序O(n^3) j往回走
//          for (int i = 0; i < size; i++) {
//              E e=get(i);
//              int j=0;
//              for ( j = i; j >0 && c.compare(get(j-1),e )>0 ; j++) {/*data[j-1]>e*/
//
//                  set(j,get(j-1));
//              }
//              set(j,e);
//          }
        //选择排序 当前元素和后面元素全部比较
        if (size == 0 || size == 1) {
            return;
        }
        Node nodeA = head;
        Node nodeB = nodeA.next;
        while (true) {
            while (true) {
                if (c.compare(nodeA.data, nodeB.data) > 0) {
                    swap(nodeA, nodeB);
                }
                if (nodeB == tail) {
                    break;
                }
                nodeB = nodeB.next;
            }
            if (nodeA.next == tail) {
                break;
            }
            nodeA = nodeA.next;
            nodeB = nodeA.next;
        }

      }

    private void swap(Node nodeA, Node nodeB) {
        E temp = nodeA.data;
        nodeA.data = nodeB.data;
        nodeB.data = temp;
    }


    @Override
    public List<E> subList(int fromIndex, int toIndex) {
     LinkedSingList<E> list =new LinkedSingList<>();
      Node nodeA =head;
        for (int i = 0; i < fromIndex; i++) {
            nodeA = nodeA.next;
        }
        Node nodeB = head;
        for (int i = 0; i < toIndex; i++) {
            nodeB = nodeB.next;
        }
        Node p = nodeA;
        while (true) {
            list.add(p.data);
            if (p == nodeB) {
                break;
            }
            p = p.next;
        }
        return list;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()){
            sb.append(']');
        }else {
            Node p = head;
            while (true){
                sb.append(p.data);
                if (p==tail){
                    sb.append(']');
                    break;
                }
                sb.append(',');
                sb.append(' ');
                p = p.next;
            }
        }
        return sb.toString();
    }

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

        class LinkedSinglyListIterator implements Iterator<E> {
            private LinkedSingList.Node cur = head;

            @Override
            public boolean hasNext() {
                return cur != null;
            }
            @Override
            public E next() {
                E ret = (E) cur.data;
                cur = cur.next;
                return ret;
            }
        }
}

单向循环链表

package p3链式结构;


import p1.List;

import java.util.Comparator;
import java.util.Iterator;
//单向循环链表
public class LinkedSinglyCircularList<E> implements List<E> {

    //定义结点对象
    private class Node{
        E data;
        Node next;
        public  Node(){
            this(null,null);
        }
        public  Node (E data){
            this(data,null);

        }

        public Node (E data, Node next ){
            this.data = data;
            this.next = next;
        }

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

    }


    private Node head;
    private Node tail;
    private int size;


    public LinkedSinglyCircularList(){
        head = null;
        tail = null;
        size=0;
    }
    public LinkedSinglyCircularList(E[] arr) {
        if (arr == null || arr.length == 0) {
            throw new IllegalArgumentException("arr is null");
        }
        for (int i = 0; i < arr.length; i++) {
            add(arr[i]);
        }
    }


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

    @Override
    public void add(int index, E element) {
        if (index<0||index>size){
            throw  new IllegalArgumentException("wrong");
        }
        //创建元素节点
        Node n = new Node(element) ;

        if (size==0){
            head=n;
            tail=n;
            tail.next =head;
        }else if (index==0){
            n.next = head;
            head = n;
            tail.next=head;
        }else if (index==size){
            n.next=tail.next;
            tail.next = n;
            tail = n;
        }else {
            Node p =head;
            for (int i = 0; i < index-1; i++) {
                p = p.next;
            }
            n.next = p.next;
            p.next = n;
        }size++;


    }

    @Override
    public void remove(E element) {
        int index = indexof(element);
        if (index != -1) {
            remove(index);
        }
    }

    @Override
    public E remove(int index) {
        if (index<0||index>=size){
            throw  new IllegalArgumentException("remove out of range");
        }
        E ret=null;
        if (size==1){
            ret = head.data;
            head = null;
            tail =null;
        }else if (index==0){
            Node n = head;
            ret=n.data;
            head=n.next;
            n.next =null;
            tail.next =head;
        }else if (index==size-1){
            Node p =head;
            while (p.next!=tail){
                p=p.next;
            }
            ret = tail.data;
            p.next =null;
            tail =p;
        }else {
            Node p =head;
            for (int i = 0; i < index-1; i++) {
                p=p.next;
            }
            Node n =p.next;
            ret = n.data;
            p.next = n.next;
            n.next = null;
        }
        size--;
        return ret;
    }

    @Override
    public E get(int index) {
        if (index<0||index>=size){
            throw  new IllegalArgumentException("get out of range");
        }

        if (index==0){
            return head.data;
        }else if (index==size-1){
            return tail.data;
        }else {
            Node p  =head;
            for (int i = 0; i < index; i++) {
                p = p.next;
            }
            return p.data;
        }

    }

    @Override
    public E set(int index, E element) {
        if (index<0||index>=size){
            throw  new IllegalArgumentException("get out of range");
        }
        E ret=null;
        if (index==0){
            ret =  head.data;

        }else if (index==size-1){
            return tail.data;
        }else {
            Node p  =head;
            for (int i = 0; i < index; i++) {
                p = p.next;
            }
            ret = p.data;
            p.data = element;
        }
        return ret;
    }

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

    @Override
    public int indexof(E element) {
        Node p =head;
        int index = 0;
        while (!p.data.equals(element)){
            p = p.next;
            index++;
            if (p==head){
                return -1;
            }
        }
        return index;
    }

    @Override
    public boolean contains(E element) {
        return indexof(element) != -1;
    }

    @Override
    public boolean isEmpty() {
        return size==0&&head ==null&&tail==null;
    }

    @Override
    public void clear() {
        head = null;
        size = 0;
        tail =null;
    }

    @Override
    public void sort(Comparator<E> c) {
        if (c==null) {
            throw new IllegalArgumentException("wrong");
        }
//          //插入排序O(n^3) j往回走
//          for (int i = 0; i < size; i++) {
//              E e=get(i);
//              int j=0;
//              for ( j = i; j >0 && c.compare(get(j-1),e )>0 ; j++) {/*data[j-1]>e*/
//
//                  set(j,get(j-1));
//              }
//              set(j,e);
//          }
        //选择排序 当前元素和后面元素全部比较
        if (size == 0 || size == 1) {
            return;
        }
       Node nodeA = head;
       Node nodeB = nodeA.next;
        while (true) {
            while (true) {
                if (c.compare(nodeA.data, nodeB.data) > 0) {
                    swap(nodeA, nodeB);
                }
                if (nodeB == tail) {
                    break;
                }
                nodeB = nodeB.next;
            }
            if (nodeA.next == tail) {
                break;
            }
            nodeA = nodeA.next;
            nodeB = nodeA.next;
        }

    }

    private void swap(Node nodeA, Node nodeB) {
        E temp = nodeA.data;
        nodeA.data = nodeB.data;
        nodeB.data = temp;
    }


    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        LinkedSingList<E> list =new LinkedSingList<>();
        Node nodeA =head;
        for (int i = 0; i < fromIndex; i++) {
            nodeA = nodeA.next;
        }
        Node nodeB = head;
        for (int i = 0; i < toIndex; i++) {
            nodeB = nodeB.next;
        }
        Node p = nodeA;
        while (true) {
            list.add(p.data);
            if (p == nodeB) {
                break;
            }
            p = p.next;
        }
        return list;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()){
            sb.append(']');
        }else {
            Node p = head;
            while (true){
                sb.append(p.data);
                if (p==tail){
                    sb.append(']');
                    break;
                }
                sb.append(',');
                sb.append(' ');
                p = p.next;
            }
        }
        return sb.toString();
    }

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

    class LinkedSinglyCircularListIterator implements Iterator<E> {
        private Node cur = head;
        private boolean flag = false;//是否跑到第一圈

        @Override
        public boolean hasNext() {
if (isEmpty()){
    return false;
}

            return flag;
        }
        @Override
        public E next() {
            E ret = (E) cur.data;
            cur = cur.next;
            if (cur==head){
                flag=false;
            }
            return ret;
        }
    }
}

双向链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

package p3链式结构;

import p1.Dequeue;
import p1.List;
import p1.Stack;

import java.util.Comparator;
import java.util.Iterator;

//双向循环链表
public class LinkedList<E> implements List<E>, Dequeue<E>, Stack<E> {
 //双端队列方法
    @Override
    public void addFirst(E element) {
        add(0, element);
    }

    @Override
    public void addLast(E element) {
        add(size, element);
    }

    @Override
    public E removeFirst() {
        return remove(0);
    }

    @Override
    public E removeLast() {
        return remove(size - 1);
    }

    @Override
    public E getFirst() {
        return get(0);
    }

    @Override
    public E getLast() {
        return null;
    }
    //链表

    private class Node{
        E data;
        Node pre; //直接前驱
        Node next; //直接后驱
        public  Node(){
            this(null,null,null);
        }
        public Node(E data){
            this(data,null,null);
        }
        public  Node(E data,Node pre,Node next){
            this.data = data;
            this.pre = pre;
            this.next= next;
        }

        @Override
        public String toString() {
            return data.toString();
        }
    }
    private Node head;
    private Node tail;
    private int  size;

    public LinkedList(){
        head=null;
        tail=null;
        size=0;
    }
    public LinkedList(E[] arr){
        if (arr ==null){
            throw  new IllegalArgumentException("arr can not be null");
        }
        for (E e:arr){
            add(e);/*默认在表尾添加元素*/
        }

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

    @Override
    public void add(int index, E element) {
      if (index<0||index>size){
          throw new IllegalArgumentException("wrong");
      }
      Node n =new Node(element);
      if (size==0){
         head =n;
         tail =n ;
         n.next=n;
         n.pre=n;

      }else if (index==0){
         n.pre =head.pre;
         n.next =head;
         head.pre=n;
         head=n;
         tail.next=head;

      }else if (index == size){
      n.next= tail.next;
      tail.next=n;
      n.pre=tail;
      tail=n;
      head.pre=tail;
      }else {
      Node p,q;
      if (index<=size/2){
          p=head;
          for (int i = 0; i < index-1; i++) {
            p=p.next;
          }
          q=p.next;
          p.next=n;
          n.pre=p;
          q.pre=n;
          n.next=q;
      }else {
          p=tail;
          for (int i = size-1; i >index ; i--) {
             p=p.pre;
          }
          q=p.pre;
          q.next =n;
          n.next =p;
          p.pre=n;
      }
      }
      size++;


    }

    @Override
    public void remove(E element) {
      int index = indexof(element);
      if (index!=-1){
          remove(index);
      }
    }

    @Override
    public E remove(int index) {
       if (index<0||index>=size){
           throw new IllegalArgumentException("remove index out of range");
       }
       E ret = null;
       Node node;
       if (size==1){
           ret = head.data;
           head = null;
           tail = null;
       }else if (index==0){
           ret=head.data;
         node = head.next;
         head.next =null;
         head.pre=node.pre;
         head.pre =null;
         head = node;
         tail.next=head;
       }else if (index == size-1){
           node = tail.pre;
           ret=tail.data;
           tail.pre=null;
           node.next=tail.next;
           tail.next = null;
           tail =node;
           head.pre = tail;

       }else {
           Node p,q,r;
           if (index<=size/2){
               p=head;
               for (int i = 0; i < index-1; i++) {
                  p=p.next;
               }
               q=p.next;
               r=q.next;
               ret= q.data;
               p.next =r;
               r.pre = p;
               q.next=null;
               q.pre=null;
           }else {
               p=tail;
               for (int i = size-1; i >index+1 ; i--) {
                 p=p.pre;
               }
               q=p.pre;
               r=q.pre;
               ret=q.data;
               r.next = p;
               p.pre =r;
               q.next=null;
               q.pre=null;
           }





       }
       size--;
       return ret;
    }

    @Override
    public E get(int index) {
       if (index<0||index>=size){
           throw new IllegalArgumentException("get out og range");
       }
       if (index==0){
           return head.data;
       }else if (index==size-1){
           return tail.data;
       }else {
           Node p =head;
           for (int i =0;i<index;i++){
               p=p.next;
           }
           return p.data;
       }
    }

    @Override
    public E set(int index, E element) {
        if (index<0||index>=size){
            throw new IllegalArgumentException("get out og range");
        }
        E ret =null;
        if (index==0){
            ret = head.data;
            head.data=element;

        }else if (index==size-1){
            ret = tail.data;
            tail.data = element;
        }else {
            Node p =head;
            for (int i =0;i<index;i++){
                p=p.next;
            }
            ret =p.data;
            p.data =element;

        }
        return ret;
    }

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

    @Override
    public int indexof(E element) {
       Node p = head;
       int index =0;
       while (!p.data.equals(element)){
           p=p.next;
           index++;
           if (p==head){
               return -1;
           }

       }
       return index;

    }

    @Override
    public boolean contains(E element) {
        return indexof(element)!=-1;
    }

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

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

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

    @Override
    public boolean isEmpty() {
        return size==0&&head == null&&tail == null;
    }

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

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

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

    @Override
    public void clear() {
      head=null;
      tail=null;
      size=0;
    }

    @Override
    public void sort(Comparator<E> c) {
      if (c==null){
          throw new IllegalArgumentException("comparator can not be null");
      }
      //插入排序来做
        if (size==0||size==1){
            return;
        }
        for (Node nodeA = head.next;nodeA!=head;nodeA =nodeA.next){
              E e =nodeA.data;
              Node nodeB;
              Node nodeC;
              for (nodeB=nodeA,nodeC =nodeB.pre;nodeC!=tail&&c.compare(nodeC.data,e)>0;nodeB=nodeB.pre,nodeC=nodeC.pre){
                nodeB.data = nodeC.data;
            }
              nodeB.data=e;
        }

    }

    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        if (fromIndex<0||toIndex>=size||fromIndex>toIndex){
            throw new IllegalArgumentException("0<=fromIndex<=toIndex<size");
        }
       Node nodeA= head;
        for (int i = 0; i < fromIndex; i++) {
            nodeA =nodeA.next;
        }
        Node nodeB= head;
        for (int i = 0;i<toIndex;i++){
            nodeB = nodeB.next;
        }
        Node p =nodeA;
        LinkedList<E>list =new LinkedList<>();
        while (true){
            list.add(p.data);
            if (p==nodeB){
                break;
            }
            p=p.next;
        }
        return list;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()){
            sb.append(']');
        }else {
            Node p = head;
            while (true){
                sb.append(p.data);
                if (p==tail){
                    sb.append(']');
                    break;
                }
                sb.append(',');
                sb.append(' ');
                p = p.next;
            }
        }
        return sb.toString();
    }

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

    class LinkedListIterator implements Iterator<E> {
        private Node cur = head;
        private boolean flag =true;
        @Override
        public boolean hasNext() {
            if (isEmpty()){
                return false;
            }
            return cur != null;
        }
        @Override
        public E next() {
            E ret = (E) cur.data;
            cur = cur.next;
            return ret;
        }
    }
    }




数独

如图,一个9*9的方阵,格子中可以填1-9,每一行不能有相同的数字,每一列也不能有相同的数字,同时每一个小的九宫格也不能有相同的数字
在这里插入图片描述
代码

package p4;

import java.io.*;


public class MathAlone {
    private static int i = 0;
    private static int[][] board = new int[9][9];

    public static void main(String[] args) throws IOException {
        readFile("MathAlone"); // 将文件中的数据读取存储在board中
        solve(0, 0);// 从0,0这个位置开始填数独,进行解题
    }

    //求解x-y格子的解 再继续向下递归求解下一个格子
    //本质求多个解 但实际 数独问题只能有一个解 如果没解 程序啥也不输出!
    private static void solve(int row, int col) {
        if (row == 9) { // 角标是0-8
            i++;
            System.out.println("===========" + i + "==========");
            printBoard();
            //System.exit(0);
        } else {
            if (board[row][col] == 0) {
                //需要填数字1~9
                for (int num = 1; num <= 9; num++) {
                    if (!isExist(row, col, num)) {
                        board[row][col] = num; //8
                        //解决下一个格子
                        solve(row + (col + 1) / 9, (col + 1) % 9);
                    }
                    //如果此处没解 必须清零
                    board[row][col] = 0;
                }
            } else {
                //已经存在一个已知数字 直接跳过去解决下一个格子
                solve(row + (col + 1) / 9, (col + 1) % 9);
            }
        }
    }

    private static boolean isExist(int row, int col, int num) {
        //同行
        for (int c = 0; c < 9; c++) {
            if (board[row][c] == num) {
                return true;
            }
        }

        //同列
        for (int r = 0; r < 9; r++) {
            if (board[r][col] == num) {
                return true;
            }
        }

        //同九宫 3*3
        int rowMin = (row / 3) * 3; // 4
        int rowMax = rowMin + 2;

        int colMin = (col / 3) * 3;
        int colMax = colMin + 2;

        for (int r = rowMin; r <= rowMax; r++) {
            for (int c = colMin; c <= colMax; c++) {
                if (board[r][c] == num) {
                    return true;
                }
            }
        }

        return false;
    }

    private static void readFile(String fileName) throws IOException {
        File file = new File(fileName);
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        String line = null;
        int row = 0;
        while ((line = br.readLine()) != null) {
            for (int col = 0; col < 9; col++) {
                board[row][col] = Integer.parseInt(line.charAt(col) + "");
            }
            row++;
        }
    }

    private static void printBoard() {
        for (int i = 0 ; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
    }
}


棋盘覆盖

在一个𝟐𝒌×𝟐𝒌 (𝒌≥𝟎)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格.显然,特殊方格在棋盘中可能出现的位置有𝟒^𝒌 种,因而有𝟒^𝒌种不同的棋盘.棋盘覆盖问题要求用4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖.
代码

package p4.分治回溯;

import java.util.Scanner;

//棋盘覆盖问题
public class ChessBoardCoverage {
    private static int BOARD_SIZE = 8;
    private static int[][] board = new int[BOARD_SIZE][BOARD_SIZE];
    //代表颜色 同一组L骨牌 编号应该是一样的
    private static int title = 0;   // 0就是特殊方格的存在

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print(">>>请输入特殊方格的角标信息:");
        //dr dc 指的是特殊方格的坐标
        int dr = input.nextInt();
        int dc = input.nextInt();

        chessBoard(0, 0, dr, dc,BOARD_SIZE);
        printBoard();
    }

    private static void printBoard() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                System.out.print(board[i][j] + "\t");
            }
            System.out.println();
        }
    }

    //在size*size的矩阵中 以tr tc为四部分子矩阵的基点 dr dc是特殊矩阵的位置 进行填充
    private static void chessBoard(int tr, int tc, int dr, int dc, int size) {
        //判断递归结束 如果尺寸为1 则不可继续拆分 则返回 归
        if (size == 1) {
            return;
        }

        //该层要填充L型骨牌 编号是一致的
        int num = ++title;
        //该层要继续分四个部分 每个部分的尺寸是多少
        int s = size / 2;

        //判断特殊方格在四个部分中 那个部分里

        //左上
        if (dr < tr + s && dc < tc + s) {
            chessBoard(tr,tc,dr,dc,s);
        } else {
            board[tr + s - 1][tc + s - 1] = num;
            chessBoard(tr,tc,tr + s - 1,tc + s - 1,s);
        }

        //右上
        if (dr < tr + s && dc >= tc + s) {
            chessBoard(tr,tc + s,dr,dc,s);
        } else {
            board[tr + s - 1][tc + s] = num;
            chessBoard(tr,tc + s,tr + s - 1,tc + s,s);
        }

        //左下
        if (dr >= tr + s && dc < tc + s) {
            chessBoard(tr + s,tc,dr,dc,s);
        } else {
            board[tr + s][tc + s - 1] = num;
            chessBoard(tr + s,tc,tr + s,tc + s - 1,s);
        }

        //右下
        if (dr >= tr + s && dc >= tc + s) {
            chessBoard(tr + s,tc + s,dr,dc,s);
        } else {
            board[tr + s][tc + s] = num;
            chessBoard(tr + s,tc + s,tr + s,tc + s,s);
        }
    }

}

8皇后问题

package p4;

public class Nqueue {
    private static  int count =0;
    private static final  int N=8;
private static int[][]arr = new int[N][N];//棋盘数据
    public static void main(String[] args) {
queue(0);
    }
//递归的解决row角标行 皇后的问题 如果把row==N 说明一个解出来了
    private static void queue(int row) {
        if (row==N){
            count++;
            System.out.println("第" +count+
                    "个解");
            printArr();
        }else {
            //遍历当前行的列
            for (int col = 0; col < N; col++) {
                if(!isDangerous(row,col)){
                    // 每次要放置皇后的时候 都先对改行进行清空
                    for (int c = 0; c < N; c++) {
                        arr[row][c] = 0;
                    }
                    arr[row][col] = 1;
                    queue(row + 1);
                }
            }
        }
    }

    private static boolean isDangerous(int row, int col) {

        //向上
        for (int r= row-1;r>=0;r--){
            if (arr[r][col]==1){
                return true;
            }
        }
        for (int r = row-1, c=col-1; r>=0&&c>=0 ; r--,c--) {
           if (arr[r][c]==1){
               return true;
           }
        }
        for (int r = row-1, c=col+1 ; r>=0&&c<N; r--,c++) {
            if (arr[r][c]==1){
                return true;
            }
        }
        return false;
    }

    private static void printArr() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                System.out.print(arr[i][j] + ",");
            }
            System.out.println();
        }
    }


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值