文章目录
了解数据
数据们之间的关系——逻辑结构
线性结构:元素是一对一关系
树形结构:元素之间存在一对多的层次关系
图形结构:元素存在多对多关系
关系在计算机上的存储——物理结构
顺序存储结构:开辟一组连续的空间存储数据
链式存储结构:开辟一组随机的空间存储数据
其中:树形结构方便查找,但是存在预留空间
而图形结构的虽然没有预留空间,但是不方便查
算法
定义是解决特地问题求解步骤的描述
算法的时间复杂度
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();
}
}
}