1.写出线性表的接口
package p2.线性表顺序;
import p1.接口.list;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
public class Arraylist<E> implements list<E> {
//数组的容器
private E[] data;
//元素的个数
private int size;
//默认容量
private static int DEFAULT_CAPACIIY=10;
//创建一个默认容量为10的线性表
public Arraylist(){
data=(E[] )new Object[DEFAULT_CAPACIIY];
size=0;
}
//创建一个指定容量的线性表
public Arraylist(int capacity){
//如果容量小于0异常
if (capacity <= 0) {
throw new IllegalArgumentException("capacity must>0");
}
DEFAULT_CAPACIIY=capacity;
data=(E[] )new Object[DEFAULT_CAPACIIY];
size=0;
}
//传入一个数组将该数组封装成一个线性表
public Arraylist(E[] arr){
if(arr==null||arr.length==0){
throw new IllegalArgumentException("arr is not be null");
}
data=(E[] )new Object[DEFAULT_CAPACIIY];
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("add index out of rang ");
}
//如果IF条件不成立执行下面
//判断线性表是否满状态,如果满了则需要扩充(resize)
if(size==data.length){
resize(2*data.length);
}
//向后移动元素
for(int i=size-1;i>=index;i--) {
//长度为4 下标为3 size为4 i=size-1=3 data【3+1】=data【3】
data[i + 1] = data[i];
}
data[index]=element;
size++;
}
//扩容//缩容
private void resize(int newlen) {
E[] newData = (E[]) new Object[newlen];
for(int i=0;i<size;i++){
//便利0到size
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 rang");
}
//先保存要删除的元素
E ret =data[index];
//移动 元素
for(int i=index+1;i<size;i++){
data[i-1]=data[i];
}
size--;
//什么时候缩容
//1.有效元素是容量的1/4
//2.当前容量不得小于等于默认容量
if (size == data.length / 4 && data.length >DEFAULT_CAPACIIY){
resize(data.length/2);
}
return ret;
}
@Override
public E get(int index) {
if(index<0||index>=size){
throw new IllegalArgumentException("get index out");
}
return data[index];
}
@Override
//修改指定角标index处的值为element,并返回原来
public E set(int index, E element) {
//先判断下标是否超出范围
if (index < 0 || index >= size) {
throw new IllegalArgumentException("set 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].equals(element)){
//如果有返回角标
return i;
}
}
return -1;
}
@Override
//包含多少元素
public boolean contains(E element) {
return indexOf(element)!=-1;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public void clear() {
//让他指向新数组
data=(E[])new Object[DEFAULT_CAPACIIY];
size=0;
}
@Override
public void sort(Comparator<E> c) {
if(c==null){
throw new IllegalArgumentException("Comparator can not be null");
}
for(int i=1;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]=data[j-1];
}data[i]=e;
}
}
@Override
public list<E> sublist(int fromIndex, int toIndex) {
if(fromIndex<0||toIndex>=size||fromIndex>toIndex){
throw new IllegalArgumentException("must 0<=fromlndex<=tolendex<=size-1");
}
Arraylist<E>list=new Arraylist<>();
for(int i=fromIndex;i<=toIndex;i++){
list.add(data[i]);
}
return list;
}
@Override
public boolean equals(Object o){
//判空
if(o==null){
return false;
}
//判自己
if(this==o){
return true;
}
//判类型
if(o instanceof Arraylist){
//按照自己的逻辑进行比较
Arraylist<E> other = (Arraylist<E>) o;
//先比有效元素的个数
if(this.size!=other.size){
return false;
}
//有效元素个数相等情况下,诸葛比较元素
for(int i=0;i<size;){
if(data[i].equals(other.data[i])){
}
}
}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();
}
@Override
public Iterator<E> iterator() {
return new ArraylistIterator();
}
//创建一个属于Arraylist的迭代器
class ArraylistIterator implements Iterator<E>{
private int cur =0;
@Override
public boolean hasNext() {//判断是否有下一个元素
return cur<size;
}
@Override
public E next() {//如果有下一个元素,把当前元素返回,并移动至下一个元素
return data[cur++];
}
}
}
2.线性表顺序的测试
package p0.测试;
import p2.线性表顺序.Arraylist;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
public class TestArraylist {
public static void main(String[] args) {
Arraylist<Integer> list = new Arraylist<>();
System.out.println(list);
Random random = new Random();
for (int i = 0; i < 10; i++) {
list.add(random.nextInt(100));
}
System.out.println(list);
for (int i=0;i<10;i++){
list.add(0,i);
}
System.out.println(list);
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
System.out.println(list);
for (Integer num:list){
System.out.println(num);
}
}
}
运行结果:
3.栈的实现
package p2.线性表顺序;
import p1.接口.Stack;
import java.util.Iterator;
public class ArrayStack<E> implements Stack<E> {
private Arraylist<E> list;
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;
}
}
栈的测试
package p0.测试;
import p2.线性表顺序.ArrayStack;
public class TestArrayStack {
public static void main(String[] args) {
ArrayStack<Integer> stack01 = new ArrayStack<>();
ArrayStack<Integer> stack02 = new ArrayStack<>(15);
for (int i=1;i<=12;i++){
stack01.push(i);
stack02.push(i);
}
System.out.println(stack01);
System.out.println(stack02); System.out.println(stack01.equals(stack02));
System.out.println(stack01.pop());
System.out.println(stack01);
System.out.println(stack01.peek());
}
}
运行结果
3.中轴计算器的实现
package p2.线性表顺序;
//中缀计算机
public class inflxCakulator {
public static void main(String[] args) {
//1.输出计算shizi
String expression ="(10+20/2*3)/2+8";
//4.如果字符串没有错,输出结果,有错输出异常
try {
//4.建立evaluateExpression函数去计算shizi然后赋值给result
int result =evaluateExpression(expression);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wrong expression :" + expression);
}
}
//4.建立的函数
private static int evaluateExpression(String expression) {
//5.建立操作符栈和数据栈
ArrayStack<Character> operatorStack = new ArrayStack<>();
ArrayStack<Integer> numberStack = new ArrayStack<>();
//3.以空格的形式将数字和非数字进行分割,输出分割后的字符
expression = inserBlanks(expression);
System.out.println(expression);
String[] tokens = expression.split(" ");
//6.遍历字符串的内容
//token 相当于从左到右的数组当中的元素
// 过滤空串
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);
}
}
//2.对原来表达式进行格式化处理 给非数字字符两边添加空格 得到一个x新的字符串
private static String inserBlanks(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();
}
}
运算结果