中缀转后缀
package p2.线性结构;
//中缀表达式转后缀表达式
public class InfixToSuffix {
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
expression = infixToSuffix(expression);
System.out.println(expression);
}
static String infixToSuffix(String expression) {
//操作符的栈
ArrayStack<String> opStack = new ArrayStack<>();
//后缀表达式的线性表
ArrayList<String> suffixList = new ArrayList<>();
//格式化表达式
expression = insertBlanks(expression);
String[] tokens = expression.split(" ");
for (String token : tokens) {
//过滤空串
if (token.length() == 0) {
continue;
}
//判断操作符+ - * /
if (isOperator(token)) {
/*
什么时候操作符进栈?
1.如果栈为空
2.如果栈顶是 (
3.如果栈顶是操作符,且优先级比当前token小
什么时候需要将栈顶操作符出栈?
1.栈顶操作符的优先级 >= 当前token
*/
while (true) {
if (opStack.isEmpty() || opStack.peek().equals("(") || priority(opStack.peek()) < priority(token)) {
opStack.push(token);
break;
}
suffixList.add(opStack.pop());
}
} else if (token.equals("(")) {
opStack.push(token);
} else if (token.equals(")")) {
while (!opStack.peek().equals("(")) {
suffixList.add(opStack.pop());
}
opStack.pop();
} else if (isNumber(token)) {
suffixList.add(token);
} else {
throw new IllegalArgumentException("wrong char :" + expression);
}
}
while (!opStack.isEmpty()) {
suffixList.add(opStack.pop());
}
//将数字元素和操作符元素进行拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < suffixList.size(); i++) {
sb.append(suffixList.get(i));
sb.append(' ');
}
return sb.toString();
}
private static int priority(String token) {
if (token.equals("+") || token.equals("-")) {
return 0;
}
if (token.equals("*") || token.equals("/")) {
return 1;
}
return -1;
}
private static boolean isNumber(String token) {
return token.matches("\\d+");
}
private static boolean isOperator(String token) {
return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
}
//对原表达式进行格式化处理 给所有的非数字字符两边添加空格
private static String insertBlanks(String expression) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
sb.append(' ');
sb.append(c);
sb.append(' ');
} else {
sb.append(c);
}
}
return sb.toString();
}
}
后缀计算器
package p2.线性结构;
//中缀表达式计算器
public class InfixCalculator {
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
try{
int result = evaluateExpression(expression);
System.out.println(result);
}catch (Exception e){
e.printStackTrace();
System.out.println("Wrong expression:" + expression);
}
}
private static int evaluateExpression(String expression) {
//需要两个辅助栈
ArrayStack<Character> operatorStack = new ArrayStack<>();
ArrayStack<Integer> numberStack = new ArrayStack<>();
//格式化表达式
expression = insertBlanks(expression);
String[] tokens = expression.split(" ");
for (String token : tokens){
//过滤空串
if(token.length() == 0){
continue;
//遍历 + -号
//如果之前是+-*/需要弹栈计算
}else if(token.equals("+") || token.equals("-")){
while (!operatorStack.isEmpty() && (operatorStack.peek() == '+' || operatorStack.peek() == '-' || operatorStack.peek() == '*' || operatorStack.peek() == '/' )){
//如果是之前别的+- 需要弹栈计算
processAnOperator(numberStack,operatorStack);
}
//入股操作符栈为空 或不为空但栈顶为(
operatorStack.push(token.charAt(0));
//遍历 */
}else if(token.equals("*") || token.equals("/")){
while (!operatorStack.isEmpty() && (operatorStack.peek() == '*' || operatorStack.peek() == '/' )){
//如果是之前别的*/ 需要弹栈计算
processAnOperator(numberStack,operatorStack);
}
//入股操作符栈为空 或不为空但栈顶为(
operatorStack.push(token.charAt(0));
//遍历(
}else if(token.equals("(")){
operatorStack.push(token.charAt(0));
//遍历到)
}else if(token.equals(")")){
//操作符栈不是( 全部弹栈计算
while (operatorStack.peek() != '('){
processAnOperator(numberStack,operatorStack);
}
//去掉左括号
operatorStack.pop();
//遍历到数字
}else{
numberStack.push(new Integer(token));
}
}
//处理最后操作符
while (!operatorStack.isEmpty()){
processAnOperator(numberStack,operatorStack);
}
return numberStack.pop();
}
//操作符栈第一个元素 数字栈弹栈两个数字 计算 并入栈数字栈
private static void processAnOperator(ArrayStack<Integer> numberStack, ArrayStack<Character> operatorStack) {
char op = operatorStack.pop();
int num1 = numberStack.pop();
int num2 = numberStack.pop();
//num2 op num1
if(op == '+'){
numberStack.push(num2 + num1);
}else if(op == '-'){
numberStack.push(num2 - num1);
}else if(op == '*'){
numberStack.push(num2 * num1);
}else{
numberStack.push(num2 / num1);
}
}
//对原表格式化处理 给非数字加空格;
private static String insertBlanks(String expression) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
sb.append(' ');
sb.append(c);
sb.append(' ');
} else {
sb.append(c);
}
}
return sb.toString();
}
}
十进制转十六进制
package p2.线性结构;
public class DecToHex {
public static void main(String[] args) {
int num = 654321;
ArrayStack<String> stack = new ArrayStack<>();
while (num != 0){
int a = num % 16;
if (a < 10){
stack.push(a + "");
}else {
stack.push((char)(a + 55) + "");
}
num /= 16;
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()){
sb.append(stack.pop());
}
System.out.println(sb.toString());
}
}
十六进制转十进制
package p2.线性结构;
public class HexToDec {
public static void main(String[] args) {
String hex = "9FBF1";
ArrayStack<Character> stack = new ArrayStack<>();
for (int i = 0; i < hex.length();i++){
stack.push(hex.charAt(i));
}
int sum = 0;
int mi = 0;
while (!stack.isEmpty()){
char c = stack.pop();
sum += getNumber(c) * Math.pow(16,mi);
mi++;
}
System.out.println(sum);
}
private static int getNumber(char c) {
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F')){
throw new IllegalArgumentException("wrong char");
}
if (c >= '0' && c <= '9'){
return c - '0';
}else {
return c - 'A' + 10;
}
}
}
回文判断
package p2.线性结构;
//判断回文
public class JudgingPalindrome {
public static void main(String[] args) {
solution01();
System.out.println(solution02());
}
private static boolean solution02() {
String text = "上海自来水来自海上";
int i =0;
int j = text.length() - 1;
while (true){
if(text.charAt(i) == text.charAt(j)){
i++;
j--;
}else {
return false;
}
if (j <= i){
return true;
}
}
}
private static void solution01() {
String text = "上海自来水来自海上";
ArrayStack<Character> stack = new ArrayStack<>();
for (int i = 0;i < text.length();i++){
if (text.length()%2 == 1 && i == text.length()/2){
continue;
}
char c = text.charAt(i);
if (stack.isEmpty()){
stack.push(c);
}else {
if (c != stack.peek()){
stack.push(c);
}else {
stack.pop();
}
}
}
System.out.println(stack.isEmpty());
}
}
括号匹配
package p2.线性结构;
import java.util.HashMap;
//括号匹配
public class MatchBracket {
public static void main(String[] args) {
solution01();
solution02();
}
private static void solution02() {
String str = "{()[[()]]<>{}()<>}";
HashMap<Character,Character> map = new HashMap<>();
map.put('[',']');
map.put('<','>');
map.put('(',')');
map.put('{','}');
ArrayStack<Character> stack = new ArrayStack<>();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (stack.isEmpty()) {
stack.push(c);
} else {
char top = stack.peek();
if (map.containsKey(top) && c == map.get(']')) {
stack.pop();
} else {
stack.push(c);
}
}
}
System.out.println(stack.isEmpty());
}
private static void solution01() {
String str = "{()[[()]]<>{}()<>}";
ArrayStack<Character> stack = new ArrayStack<>();
for (int i = 0; i < str.length();i++){
char c = str.charAt(i);
if (stack.isEmpty()){
stack.push(c);
}else {
char top = stack.peek();
if (top - c == -1 || top - c == -2){
stack.pop();
}else {
stack.push(c);
}
}
}
System.out.println(stack.isEmpty());
}
}
双端栈
在一个线性表的两端做栈底分别进行入栈和出栈操作
主要利用栈 栈底位置不变,栈顶位置动态变化 特性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggWcrHJu-1642155306472)(C:\Users\qwe123\AppData\Roaming\Typora\typora-user-images\image-20220113092736512.png)]
双端站是线性表的一种 栈的一个特殊分类
用动态数组实现双端栈
package p2.线性结构;
//双端栈
import java.util.Arrays;
import java.util.Iterator;
public class ArrayDoubleEndStack<E> implements Iterable<E> {
//左端栈顶
private int ltop;
//右端栈顶
private int rtop;
//存储元素容器
private E[] data;
//数组容器默认容量
private static int DEFAULT_CAPACITY = 10;
public ArrayDoubleEndStack(){
data = (E[]) new Object[DEFAULT_CAPACITY];
ltop = -1;
rtop = data.length;
}
//进栈
public void pushLeft(E element){
if (ltop + 1 == rtop){
resize(data.length * 2);
}
data[++ltop] = element;
}
public void pushRlght(E element){
if (ltop + 1 == rtop){
resize(data.length * 2);
}
data[--rtop] = element;
}
//resize 扩容 缩容
private void resize(int newLen) {
E[] newData = (E[]) new Object[newLen];
//复制左端元素
for (int i = 0;i <= ltop;i++){
newData[i] = data[i];
}
//复制右端元素
int index = rtop;
for (int i = newLen - sizeRight(); i < newLen;i++){
newData[i] = data[index++];
}
rtop = newLen - sizeRight();
data = newData;
}
//出栈
public E popLeft(){
if (isLeftEmpty()){
throw new IllegalArgumentException("Left null");
}
E ret = data[ltop--];
if (sizeLeft() + sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY){
resize(data.length / 2);
}
return ret;
}
public E popRight(){
if (isRightEmpty()){
throw new IllegalArgumentException("Right null");
}
E ret = data[rtop++];
if (sizeLeft() + sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY){
resize(data.length / 2);
}
return ret;
}
//栈顶
public E peekLeft(){
if (isLeftEmpty()){
throw new IllegalArgumentException("Left null");
}
return data[ltop];
}
public E peekRight(){
if (isRightEmpty()){
throw new IllegalArgumentException("Right null");
}
return data[rtop];
}
public boolean isLeftEmpty(){
return ltop == -1;
}
public boolean isRightEmpty(){
return rtop == data.length;
}
public int sizeLeft(){
return ltop + 1;
}
public int sizeRight(){
return data.length - rtop;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
if (isLeftEmpty() && isRightEmpty()){
sb.append(']');
return sb.toString();
}
//左右都不空 先左
for (int i = 0;i <= ltop;i++){
sb.append(data[i]);
if (i == ltop && isRightEmpty()){
sb.append(']');
return sb.toString();
}else {
sb.append(',');
}
}
//右边
for (int i = rtop; i < data.length;i++){
sb.append(data[i]);
if (i == data.length - 1){
sb.append(']');
}else {
sb.append(',');
}
}
return sb.toString();
}
@Override
public Iterator<E> iterator() {
return new ArrayDoubleEndStackIterator();
}
class ArrayDoubleEndStackIterator implements Iterator<E>{
private ArrayList<E> list;
private Iterator<E> it;
public ArrayDoubleEndStackIterator(){
list = new ArrayList<>();
for (int i = 0;i <= ltop;i++){
list.add(data[i]);
}
for (int i = rtop;i < data.length;i++){
list.add(data[i]);
}
it = list.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public E next() {
return it.next();
}
}
}
package p0.测试;
import p2.线性结构.ArrayDoubleEndStack;
public class TestArrayDoubleEndStack {
public static void main(String[] args) {
ArrayDoubleEndStack<Integer> stack01 = new ArrayDoubleEndStack<>();
System.out.println(stack01);
for (int i = 0; i < 10;i++){
stack01.pushLeft(i);
}
System.out.println(stack01);
ArrayDoubleEndStack<Integer> stack02 = new ArrayDoubleEndStack<>();
System.out.println(stack02);
for (int i = 0; i < 10;i++){
stack02.pushRlght(i);
}
System.out.println(stack02);
ArrayDoubleEndStack<Integer> stack03 = new ArrayDoubleEndStack<>();
System.out.println(stack03);
for (int i = 0; i < 10;i++){
stack03.pushLeft(i);
stack03.pushRlght(i);
}
System.out.println(stack03);
for (Integer num: stack03) {
System.out.println(num);
}
}
}
队列
只允许在一端插入 在另一端删除的线性表
删除的一端叫队首 插入的一端叫队尾
不含任何元素叫空队列 先进先出
插入叫入队 删除叫出队
package p1.接口;
public interface Queue<E> extends Iterable<E> {
//入队
public void offer(E element);
//出队
public E poll();
//查看队首元素
public E peek();
public boolean isEmpty();
public void clear();
public int size();
}
package p2.线性结构;
import p1.接口.Queue;
import java.util.Iterator;
import java.util.Objects;
public class ArrayQueue<E> implements Queue<E> {
private ArrayList<E> list;
public ArrayQueue(){
list = new ArrayList<>();
}
@Override
public void offer(E element) {
list.add(list.size(),element);
}
@Override
public E poll() {
return list.remove(0);
}
@Override
public E peek() {
return list.get(0);
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public void clear() {
list.clear();
}
@Override
public int size() {
return list.size();
}
@Override
public Iterator<E> iterator() {
return list.iterator();
}
@Override
public String toString() {
return list.toString();
}
@Override
public boolean equals(Object o) {
if (o == null){
return false;
}
if (this == o){
return true;
}
if (o instanceof ArrayQueue){
ArrayQueue other = (ArrayQueue) o;
return list.equals(other.list);
}
return false;
}
}
package p0.测试;
import p2.线性结构.ArrayQueue;
public class TestArrayQueue {
public static void main(String[] args) {
ArrayQueue<Integer> queue = new ArrayQueue<>();
for (int i = 1; i <= 10;i++){
queue.offer(i);
}
System.out.println(queue);
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue);
}
}
文件夹遍历
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x09yaGJZ-1642155306474)(C:\Users\qwe123\AppData\Roaming\Typora\typora-user-images\image-20220113112803447.png)]
package p2.线性结构;
import java.io.File;
//文件夹遍历
public class DirectoryTraversal {
public static void main(String[] args) {
/*
只要队列不为空 出一个目录对象
将该目录对象展开 遍历 遇到文件打印名称 遇到其他目录进队
*/
File dir = new File("C:\\Users\\qwe123\\Documents\\WeChat Files\\wxid_0674puy2lnqz21\\FileStorage\\File\\2022-01\\Day04\\DS");
ArrayQueue<File> queue = new ArrayQueue<>();
queue.offer(dir);
while (!queue.isEmpty()){
File file = queue.poll();
System.out.println("【"+ file.getName() + "】");
File[] files = file.listFiles();
for (File f : files){
if (f.isFile()){
System.out.println(f.getName());
}else {
queue.offer(f);
}
}
}
}
}
栈实现队列
package p2.线性结构;
import p1.接口.Queue;
import java.util.Iterator;
//栈实现队列
public class StackToQueue {
public static void main(String[] args) {
QueueImpByStack<Integer> queue = new QueueImpByStack<>();
for (int i = 1;i <= 5 ;i++){
queue.offer(i);
}
System.out.println(queue);
System.out.println(queue.poll());
System.out.println(queue);
}
}
class QueueImpByStack<E> implements Queue<E> {
private ArrayStack<E> stackA;
private ArrayStack<E> stackB;
public QueueImpByStack(){
stackA = new ArrayStack<>();
stackB = new ArrayStack<>();
}
@Override
public void offer(E element) {
stackA.push(element);
}
@Override
public E poll() {
if (isEmpty()){
throw new IllegalArgumentException("queue null");
}
while (stackA.size() != 1){
stackB.push(stackA.pop());
}
E ret = stackA.pop();
while (!stackB.isEmpty()){
stackA.push(stackB.pop());
}
return ret;
}
@Override
public E peek() {
if (isEmpty()){
throw new IllegalArgumentException("queue null");
}
while (stackA.size() != 1){
stackB.push(stackA.pop());
}
E ret = stackA.peek();
while (!stackB.isEmpty()){
stackA.push(stackB.pop());
}
return ret;
}
@Override
public boolean isEmpty() {
return stackA.isEmpty();
}
@Override
public void clear() {
stackA.clear();
}
@Override
public int size() {
return stackA.size();
}
@Override
public Iterator<E> iterator() {
return null;
}
@Override
public String toString() {
return stackA.toString();
}
}
队列实现栈
package p2.线性结构;
import p1.接口.Stack;
import java.util.Iterator;
//队列实现栈
public class QueueToStack {
public static void main(String[] args) {
StackImplByQueue<Integer> stack = new StackImplByQueue<>();
System.out.println(stack);
for (int i = 1; i <= 5; i++) {
stack.push(i); //队列A
}
System.out.println(stack.toString());
System.out.println(stack.pop());
System.out.println(stack); //队列B
}
}
class StackImplByQueue<E> implements Stack<E> {
private ArrayQueue<E> queueA;
private ArrayQueue<E> queueB;
public StackImplByQueue() {
queueA = new ArrayQueue<>();
queueB = new ArrayQueue<>();
}
@Override
public int size() {
if (queueA.isEmpty() && queueB.isEmpty()) {
return 0;
} else if (!queueA.isEmpty()) {
return queueA.size();
} else {
return queueB.size();
}
}
@Override
public boolean isEmpty() {
return queueA.isEmpty() && queueB.isEmpty();
}
@Override
public void push(E element) {
if (queueA.isEmpty() && queueB.isEmpty()) {
queueA.offer(element);
} else if (!queueA.isEmpty()) {
queueA.offer(element);
} else {
queueB.offer(element);
}
}
@Override
public E pop() {
if (isEmpty()) {
return null;
}
E ret = null;
if (!queueA.isEmpty()) {
while (queueA.size() != 1) {
queueB.offer(queueA.poll());
}
ret = queueA.poll();
} else {
while (queueB.size() != 1) {
queueA.offer(queueB.poll());
}
ret = queueB.poll();
}
return ret;
}
@Override
public E peek() {
if (isEmpty()) {
return null;
}
E ret = null;
if (!queueA.isEmpty()) {
while (queueA.size() != 1) {
queueB.offer(queueA.poll());
}
ret = queueA.poll();
queueB.offer(ret);
} else {
while (queueB.size() != 1) {
queueA.offer(queueB.poll());
}
ret = queueB.poll();
queueA.offer(ret);
}
return ret;
}
@Override
public void clear() {
queueA.clear();
queueB.clear();
}
@Override
public Iterator<E> iterator() {
if (isEmpty()) {
return queueA.iterator();
} else if (!queueA.isEmpty()) {
return queueA.iterator();
} else {
return queueB.iterator();
}
}
@Override
public String toString() {
if (isEmpty()) {
return "[]";
} else if (!queueA.isEmpty()) {
return queueA.toString();
} else {
return queueB.toString();
}
}
}
回顾Array Queue
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5p5oZUhv-1642155306476)(C:\Users\qwe123\AppData\Roaming\Typora\typora-user-images\image-20220113191529649.png)]
循环队列ArrayLoopQueue
该循环队列的实现思想是动态数组
package p2.线性结构;
import p1.接口.Queue;
import java.io.SequenceInputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
//循环队列
public class ArrayLoopQueue implements Queue {
//存储数据容器
private E[] data;
//对首指针
private int front;
//队尾指针
private int rear;
//元素个数(f<r r-F ; r<f r+L-f)
private int size;
//默认容量
private static int DEFAULT_CAPACITY = 10;
public ArrayLoopQueue(){
data = (E[]) new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public void offer(E element) {
if ((rear + 1) % data.length == front){
resize(data.length * 2 - 1);
}
data[rear] = element;
rear = (rear + 1) % data.length;
size++;
}
@Override
public E poll() {
if (isEmpty()){
throw new IllegalArgumentException(“queue null”);
}
E ret = data[front];
front = (front + 1) % data.length;
size–;
if(size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY){
resize(data.length / 2 +1);
}
return ret;
}
private void resize(int newLen) {
E[] newData = (E[]) new Object[newLen];
int index = 0;
for (int i = front; i != rear;i = (i + 1) % data.length){
newData[index++] = data[i];
}
data = newData;
front = 0;
rear = index;
}
@Override
public E peek() {
if (isEmpty()){
throw new IllegalArgumentException(“queue null”);
}
return data[front];
}
@Override
public boolean isEmpty() {
return front == rear;
}
@Override
public void clear() {
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
front = 0;
rear = 0;
}
@Override
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(’[’);
if (isEmpty()){
sb.append(’]’);
return sb.toString();
}
for (int i = front; i != rear ; i = (i + 1) % data.length){
sb.append(data[i]);
if ((i + 1 % data.length == rear)){
sb.append(’]’);
}else {
sb.append(’,’);
sb.append(’ ');
}
}
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (o == null){
return false;
}
if (this == o){
return true;
}
if (o instanceof ArrayLoopQueue){
ArrayLoopQueue other = (ArrayLoopQueue) o;
if (size != other.size){
return false;
}
int i = front;
int j = other.front;
while (i != rear){
if (data[i].equals(other.data[j])){
return false;
}
i = (i + 1) % data.length;
j = (j + 1) % other.data.length;
}
return true;
}
return false;
}
@Override
public Iterator iterator() {
return null;
}
class ArrLoopQueueIterator implements Iterator{
private int cur = front;
@Override
public boolean hasNext() {
return cur != rear;
}
@Override
public E next() {
E ret = data[cur];
cur = (cur + 1) % data.length;
return ret;
}
}
}
package p2.线性结构;
import java.io.File;
//文件夹遍历
public class DirectoryTraversal {
public static void main(String[] args) {
/*
只要队列不为空 出一个目录对象
将该目录对象展开 遍历 遇到文件打印名称 遇到其他目录进队
*/
File dir = new File("C:\\Users\\qwe123\\Documents\\WeChat Files\\wxid_0674puy2lnqz21\\FileStorage\\File\\2022-01\\Day04\\DS");
ArrayLoopQueue<File> queue = new ArrayLoopQueue<>();
queue.offer(dir);
while (!queue.isEmpty()){
File file = queue.poll();
System.out.println("【"+ file.getName() + "】");
File[] files = file.listFiles();
for (File f : files){
if (f.isFile()){
System.out.println(f.getName());
}else {
queue.offer(f);
}
}
}
}
}
双端队列
限定插入和删除操作在表两端的线性表
是具有队列和栈的性质的数据结构
package p1.接口;
public interface Dequeue<E> extends Queue<E> {
public void addFirst(E element);
public void addLast(E element);
public E removeFirst();
public E reomveLast();
public E getFirst();
public E getLast();
}
package p2.线性结构;
import p1.接口.Dequeue;
import p1.接口.Stack;
import java.util.Arrays;
import java.util.Iterator;
public class ArrayDeque<E> implements Dequeue<E>, Stack<E> {
private E[] data;
private int front;
private int rear;
private int size;
private static int DEFAULT_CAPACITY = 10;
public ArrayDeque() {
data = (E[]) new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public void addFirst(E element) {
if ((rear + 1) % data.length == front) {
resize(data.length * 2 - 1);
}
front = (front - 1 + data.length) % data.length;
data[front] = element;
size++;
}
private void resize(int newLen) {
E[] newData = (E[]) new Object[newLen];
int index = 0;
for (int i = front; i != rear; i = (i + 1) % data.length) {
newData[index++] = data[i];
}
data = newData;
front = 0;
rear = index;
}
@Override
public void addLast(E element) {
if ((rear + 1) % data.length == front) {
resize(data.length * 2 - 1);
}
data[rear] = element;
rear = (rear + 1) % data.length;
size++;
}
@Override
public E removeFirst() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
E ret = data[front];
front = (front + 1) % data.length;
size--;
if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return null;
}
@Override
public E reomveLast() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
rear = (rear - 1 + data.length) % data.length;
E ret = data[rear];
size--;
if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return ret;
}
@Override
public E getFirst() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
return data[front];
}
@Override
public E getLast() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
return data[(rear - 1 + data.length) % data.length];
}
@Override
public void offer(E element) {
addLast(element);
}
@Override
public E poll() {
return removeFirst();
}
@Override
public E element() {
return getFirst();
}
@Override
public E peek() {
return getLast();
}
@Override
public boolean isEmpty() {
return size == 0 && front == rear;
}
@Override
public void push(E element) {
addLast(element);
}
@Override
public E pop() {
return reomveLast();
}
@Override
public void clear() {
E[] data = (E[]) new Object[DEFAULT_CAPACITY];
front = 0;
rear = 0;
size = 0;
}
@Override
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
if (isEmpty()) {
sb.append(']');
return sb.toString();
}
for (int i = front; i != rear; i = (i + 1) % data.length) {
sb.append(data[i]);
if ((i + 1) % data.length == rear) {
sb.append(']');
} else {
sb.append(',');
sb.append(' ');
}
}
return sb.toString();
}
@Override
public Iterator<E> iterator() {
return new ArrayDequeIterator();
}
class ArrayDequeIterator implements Iterator<E> {
private int cur = front;
@Override
public boolean hasNext() {
return cur != rear;
}
@Override
public E next() {
E ret = data[cur];
cur = (cur + 1) % data.length;
return ret;
}
}
}