由于数组是固定长度的数据结构,
但是某个时候我们需要额外的数据结构。
一般来说,有表list这种数据结构。队列,栈,堆
表分为:
数组列表,链表,单链表,单循环双循环。
为什么要活动数组?
因为数组中插入元素和删除元素很费时间,要移动整个数组。而且不方便 我们数据量不确定的时候。
一般有下面两种表
ArrayList和Vector.
但我一般用ArrayList。这样更方便一点。两者基本用法差不多。
public class d6 {
public static void main(String[] args) {
Vector<Integer> vector = new Vector<Integer>();
vector.add(3);
vector.add(3);
vector.add(3);
vector.add(3);
vector.addElement(4);
vector.add(2,2);
System.out.println(vector.indexOf(2));
System.out.println(vector);
}
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(3);
arrayList.add(3);
arrayList.add(3);
arrayList.add(3);
arrayList.add(2,2);
System.out.println(arrayList.indexOf(2));
System.out.println(arrayList);
队列
队列是先进先出的数据结构
Queue<Integer> queue = new LinkedList<Integer>();
记得用LinkList实现多态。
Queue<Integer> queue = new LinkedList<Integer>();
for (int i = 0; i < 10; i++) {
queue.offer(i);
}
queue.add(3);//添加,但是失败会返回异常
queue.poll();//删除并返回头
queue.remove();//删除并返回头,但是失败会抛出异常
queue.remove(2);//删除2
System.out.println(queue.contains(5));
queue.element();//返回头,空或其他会抛出异常
queue.peek();//返回头,空为null。
常用方法如上,注意异常的区别哦,poll 与remove;add与offer
例题5.3猫狗收容所
但是,如果只设计。
就是简单来说,仅仅一个队列无法满足猫狗出队。
如果用两个的话又无法满足,顺序出队
这里就要设计一个类。用一个计数器来写它的入队顺序号。
Queue<Animal> dog = new LinkedList<>();
Queue<Animal> cat = new LinkedList<>();
class Animal{
int num;
int obj;
Animal(){}
Animal(int num,int obj){
this.num = num;
this.obj = obj;
}
}
思路就在上面了,细节就自己实现把,反正不是太麻烦,去打羽毛球咯。
回来了,回来了。
补上
public class e2 {
static int obj =1;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int first = scanner.nextInt();//确定收养方式1,入队;2出队
int second = scanner.nextInt();
Queue<Animal> dog = new LinkedList<>();
Queue<Animal> cat = new LinkedList<>();
queue(1,3,dog,cat);
}
static boolean queue(int first, int second, Queue<Animal> dog, Queue<Animal> cat){
if(first!=1||first!=2)return false;
if(first==1){
if(second==0)return false;
else if(second>0){
dog.offer(new Animal(second,obj));
obj++;
}else if(second<0){
cat.offer(new Animal(second,obj));
obj++;
}
return true;
}
else if(first==2){
if(second==0){
if(dog.peek().obj<cat.peek().obj){
Animal poll = dog.poll();
System.out.println(poll.num);
}else {
Animal poll = cat.poll();
System.out.println(poll.num);
}
}else if(second==1){
System.out.println(dog.poll().num);
}else if(second==2){
System.out.println(cat.poll().num);
}
}
return false;
}
}
例题
前缀,中缀,后缀表达式。
括号>乘除>加减
举例:
(3 + 4) × 5 - 6 就是中缀表达式
- × + 3 4 5 6 前缀表达式
3 4 + 5 × 6 - 后缀表达式
一般来说,可以用栈来实现。
顺序实现一般是
设计两个栈
一个栈用来存符号,一个栈用来存数字
每次从数字栈拿出2个数字,符号栈拿出一个符号。
压入栈要判断是否为空,数字栈设计一个最低优先级的字符$,字符栈设计一个最低优先级的字符#来避免每次弹出的时候判断是否为栈底
暂时空着。。。
弄得有点头疼
- 遍历整个字符串查看每个字符
- 如果是数字,直接入数栈
- 如果是运算符,分下面几种情况
- 如果符号栈为空,直接入栈,
- 如果符号栈不为空,就比较当前符号的优先级是否等于栈顶符号的优先级。如果是,就从数栈pop出两个数,从符号栈pop一个运算符,然后把这两个数的运算结果push到数栈中。运算符再入符号栈,如果大于栈顶符号优先级,直接符号栈。
- 当整个字符串遍历完成后,就顺序的从两个栈pop出相应的数字和符号进行运算。最后数栈剩下的唯一一个元素就是结果。
换句话说,也就是入栈的时候,先把乘除算好。最后再算加减。
那么我有一种新的思路,就是每当遇到乘除符号的时候,先入栈,pop一个数,再读取一个数,对其运算,然后push数栈。