HomeWork0 和 project0 没有
HomeWork0太简单了
project0 看着太烦躁了 所以就从project1a开始
这个博客先放到这里 后面慢慢填坑
gitee在这里
这个部分主要参考了一位github大神
这位大神的github也放到这里了
project1a
LinkedListDeque
public class LinkedListDeque<Generic> {
//泛型节点类
private class GenericNode {
public Generic item;
public GenericNode next;
public GenericNode prev;
public GenericNode(Generic i, GenericNode n, GenericNode p) {
item = i;
next = n;
prev = p;
}
}
//属性
private final GenericNode sentinel; //哨兵节点
private int size; //缓存长度
//无参构造
public LinkedListDeque() {
sentinel = new GenericNode(null, null, null);
sentinel.next = sentinel;
sentinel.prev = sentinel;
size = 0;
}
//全参构造
public LinkedListDeque(Generic x) {
sentinel = new GenericNode(null, null, null);
GenericNode node = new GenericNode(x, sentinel, sentinel);
sentinel.next = node;
sentinel.prev = node;
size = 1;
}
//深拷贝
public LinkedListDeque(LinkedListDeque<Generic> other) {
sentinel = new GenericNode(null, null, null);
sentinel.next = sentinel;
sentinel.prev = sentinel;
size = other.size();
// 将要拷贝的队列进行遍历 将遍历的item添加到新建队列的末尾 从而实现深拷贝
for (int i = 0; i < other.size(); i++) addLast(other.get(i));
}
//开头插入
public void addFirst(Generic x) {
GenericNode node = new GenericNode(x, sentinel.next, sentinel);
sentinel.next.prev = node;
sentinel.next = node;
size++;
}
//结尾插入
public void addLast(Generic x) {
GenericNode node = new GenericNode(x, sentinel, sentinel.prev);
sentinel.prev.next = node;
sentinel.prev = node;
size++;
}
//为空判定
public boolean isEmpty() {
return size == 0;
}
//队列长度
public int size() {
return size;
}
//打印队列内容
public void printDeque() {
GenericNode p = sentinel.next;
while (p != sentinel) {
System.out.print(p.item + " ");
p = p.next;
}
System.out.println();
}
//删除队列开始的对象
public Generic removeFirst() {
if (sentinel.next == sentinel) return null;
Generic item = sentinel.next.item;
sentinel.next.next.prev = sentinel;
sentinel.next = sentinel.next.next;
size--;
return item;
}
//删除队列结尾的对象
public Generic removeLast() {
if (sentinel.prev == sentinel) return null;
Generic item = sentinel.prev.item;
sentinel.prev.prev.next = sentinel;
sentinel.prev = sentinel.prev.prev;
size--;
return item;
}
//迭代获取队列中的指定索引
public Generic get(int i) {
GenericNode p = sentinel.next;
if (i >= size) return null;
int j = 0;
while (i != j) {
p = p.next;
j++;
}
return p.item;
}
//递归获取队列中的指定索引
private GenericNode getRecursive(GenericNode node, int index) {
if (index == 0) return node.next;
return getRecursive(node.next, --index);
}
public Generic getRecursive(int index) {
return getRecursive(sentinel, index).item;
}
//主函数
public static void main(String[] args) {
LinkedListDeque<Integer> L2 = new LinkedListDeque<>(15);
L2.addFirst(10);
L2.addFirst(5);
L2.addLast(20);
L2.printDeque();
System.out.println(L2.removeFirst());
L2.printDeque();
System.out.println(L2.removeLast());
L2.printDeque();
System.out.println(L2.getRecursive(1));
}
}
ArrayDeque
- 这个部分主要参考了那位github 大神 没有他的启发我是写不出来的
- 这位大神的github的java位置
public class ArrayDeque<Type> {
private Type[] items; //用于存储对象
private int nextFirst; //数组开始前的标志位 类似于sentinel的prev
private int nextLast; //数组最后的的标志位 类似于sentinel的next
private int size; //数组的长度缓存
/**
* 无参初始化
*/
public ArrayDeque() {
items = (Type[]) new Object[8];
nextFirst = 0;
nextLast = 1;
size = 0;
}
/**
* 深度拷贝 拷贝时重排
* 拷贝之后改变了数组结构 将其进行了重排 不知道这样是不是符合要求
* @param other
*/
public ArrayDeque(ArrayDeque<Type> other) {
items = other.items;
resize(other.items.length,other);
}
/**
* 深度拷贝 拷贝时不重排 也可以使用 解除注释即可
*
* @param other
*/
// public ArrayDeque(ArrayDeque<Type> other) {
//
// items = (Type[]) new Object[other.items.length];
//
//
// int index = plusOne(other.nextFirst);
// while (index !=other.nextLast){
// items[index] = other.items[index];
// index = plusOne(index);
// }
//
// size = other.size;
// nextFirst = other.nextFirst;
// nextLast = other.nextLast;
//
// }
/**
* 数组根据输入的长度 和指定的Array队列 进行重建
* src参数主要用于 拷贝其他数组进行使用
* 重建的过程中 还进行了数组重排序
* 将原来从索引 plusOne(nextFirst) 到 minusOne(nextLast) 区间内的值
* 重新排序到新数组中 从索引 0 到size-1的值
* @param capacity
* @param other
*/
private void resize(int capacity , ArrayDeque<Type> src) {
Type[] target = (Type[]) new Object[capacity];
int oldIndex = plusOne(src.nextFirst);
for (int i = 0; i < src.size; i++) {
target[i] = src.items[oldIndex];
oldIndex = plusOne(oldIndex);
}
items = target;
nextFirst = capacity - 1;
nextLast = src.size;
size = src.size;
}
/**
* 数组扩容
*/
private void upSize() {
resize(size * 2);
}
/**
* 数组降容
*/
private void downSize() {
resize(size / 2);
}
/**
* 数组根据输入的长度进行重建
* 主要针对自己的Array队列进行扩容和降容操作
* 函数内容是调用了重载方法 并使用了this作为默认值
* @param capacity
*/
private void resize(int capacity) {
resize(capacity,this);
}
//原来放在这里的代码 现在已经放到了重载函数中
/* Type[] target = (Type[]) new Object[capacity];
int oldIndex = plusOne(nextFirst);
for (int i = 0; i < size; i++) {
target[i] = items[oldIndex];
oldIndex = plusOne(oldIndex);
}
items = target;
nextFirst = capacity - 1;
nextLast = size;*/
/**
* 数组是否扩容判定
*
* @return
*/
private boolean isFull() {
return size == items.length;
}
/**
* 数组是否降容判定
* 主要依据为数组的存储效率
* 当数组容量大于16 且数组中存放item的数目size 小于整个数组空间的25%
* 会将数组降容 以节省空间
*
* @return
*/
private boolean isSparse() {
return items.length >= 16 && size < (items.length / 4);
}
/**
* 在双端队列中 是由循环关系的
* 因此 nextFirst nextLast 不能只考虑 自增和自减
* 要把循环考虑进去
*
* @param index
* @return
*/
private int plusOne(int index) {
return (index + 1) % items.length;
}
private int minusOne(int index) {
return (index - 1 + items.length) % items.length;
}
/**
* 首位添加
*
* @param item
*/
public void addFirst(Type item) {
if (isFull()) upSize();
items[nextFirst] = item;
nextFirst = minusOne(nextFirst);
size++;
}
/**
* 末位添加
*
* @param item
*/
public void addLast(Type item) {
if (isFull()) upSize();
items[nextLast] = item;
nextLast = plusOne(nextLast);
size++;
}
/**
* 空集判定
*
* @return
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 长度输出
*
* @return
*/
public int size(