2019-10-12 20:26:25
练习1 •:实现整形数组对象
建立数组类ArrayList,写出数组的指定位置增加元素、在尾部增加元素的方法、删除指定位置元素、删除指定值元素的方法
数组类的属性:定义数组名private int array[]; 定义数组长度private int size;
添加构造函数:public ArrayList(){} 在添加一个构造函数,使用户可以改变数组的长度public ArrayList(int size){this.array[]=new int[size];this.size=0;}
两个构造函数的连接:在无参数的构造函数里添加this语句,指向下面的参数语句:public ArrayList(){this(0);}
方法:1.数组的指定位置(index号)增加元素val
public void add(int index,int val){
if(index<0||index>this.arr.length){
throw new IllegalArgumentException(index + "invalid");
}
if(this.size==this.array.length){
this.array=Arrays.copyOf(this.array,this,size*2);
}
for(int i=index;i<this.array.length;i++){
array[i+1]=array[i];
}
this.array[index]=val;
this.size--;
}
错误总结:copyOf函数的用法 缺少this谨记!!! 抛出异常的用法throw new IllegalArgumentException(index);
2.向尾部增加元素
public void add(int val){
if(this.size==this.array.length){
this.array=Arrays.copyOf(this.array,this,size*2);
}
array[index]=val;
size++;
}
3.删除指定位置的元素
public void del(int index){
if(index<0||index>this.arr.length){
throw new IllegalArgumentException(index + "invalid");
}
for(int i=index;i<this.array.length;i++){
this.array[i]=this.array[i+1];
}
this.size--;
}
4.删除指定元素的值
public void del(int val){
int index=-1;
for(int i=0;i<this.array.length;i++){
if(val==this.array[i]){
index=i;
break;
}
}
if(index=-1){
return;}
for(int index=-1;i<this.size-1;i++){
this.arr[i]=this.array[i+1];
}
this.size--;
}
5.数组对象的打印,此时数组是对象,需要将它放在一个字符串里进行打印
public String toString(){
String arr=new String();
for(int i=0;i<this.size;i++){
arr=arr+this.arr[i];
}
return arr;
}
也可以直接打印数组
public void tooString(){
for(int i=0;i<arr[i].size;i++){
arr[i]=arr[i]+" ";
System.out.print(arr[i]);
}
}
import java.util.*; import java.util.Arrays; /** * 实现整形数组对象 */ class ArrayList{ //用来存储元素 protected int[] array; //用来记录元素的个数 protected int size=0; //alt + Insert 构造函数 public ArrayList() { // this.array = new int[10]; // this.size=0; this(1);//调用其他的带一个int型参数的构造函数(下面是函数的具体实现) } //好处是用户可以自定义输入的数组大小 public ArrayList(int size) { this.array = new int[size]; this.size=0; } //缩容 把内存空间缩小到有效元素个数的长度 public void trimToSzie(int[] array){ this.array=Arrays.copyOf(this.array,size); } //向尾部增加元素 public void add(int val){ //判断空间是否足够,不够或者够都要添加元素 if(this.size==this.array.length){ this.array=Arrays.copyOf(this.array,size*2); } this.array[this.size++]=val; // array[array.length]=val; } //向指定位置增加元素 public void add(int index,int val){ if(index<0 || index>=size) { //参数不合法,抛出异常 throw new IllegalArgumentException(index + "invalid"); } //扩容数组 if(this.size==this.array.length){ this.array=Arrays.copyOf(this.array,size*2); } //移动元素 for (int i = size;i>index;i--) { array[i] = array[i-1]; } //给index号位置添加元素 this.array[index] = val; this.size++;//更新元素个数 } //删除index号元素的值 public void del(int index){ if(index<0 || index>=size) { //参数不合法,抛出异常 throw new IllegalArgumentException(index + "invalid"); } for(int i=index;i<this.size;i++){ this.array[i]=this.array[i+1]; } this.size--; } //删除为val的元素 public void remove(int val){ if(size==0){ throw new IllegalArgumentException("invalid"); } //在数组中利用for循环查找val int index=-1; for(int i=0;i<this.size;i++){ if(this.array[i]==val){ index=i; break; } } //不存在这个值的情况,index不会改变,直接返回 if(index==-1){ return; } //再将该值后边的数依次前移 for(int i=index;i<this.size-1;i++){ this.array[i]=this.array[i+1]; } this.size--; } //将数组放在一个字符串里面的打印,因为这时的数组是数组对象 public String toString() { String arr = new String(); for (int i = 0; i < this.size; i++) { arr = arr + this.array[i] + " "; } return arr; } } public class ArrayListTest { public static void main(String[] args) { Random rd = new Random(); ArrayList list = new ArrayList(8); //产生0-10之间的随机数给数组 for (int i = 0; i < 10; i++) { list.add(rd.nextInt(50)); } System.out.println(list); list.add(2,16); System.out.println(list.toString()); list.remove(2);//删除值为2的元素 System.out.println(list.toString()); list.del(3);//删除索引为3的元素 System.out.println(list.toString()); } }
练习2•: 顺序队列类
队列的特征:先进先出,后进后出。队头进行删除,队尾进行添加。
初始化建立空队列时,令front=rear=0;每当插入新的队列尾元素时,“尾指针增1”,每当删除队列头元素时,“头指针增1”。
因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置。
定义队类的属性:int front; int rear; int[] queue(用来存放队列的元素);
队列的相关方法:入队列、出队列、判断队列空与满,返回队头元素与队列长度
构造函数对队列定义大小
public Queue(){this(10);}
public Queue(int size){this.Queue=new int[size];this.front=0;this.rear=0;}
方法1:在队尾进行添加元素(判断是否队列满)
public void offer(int val){
if(this.full()){
this.queue=Arrays.copyOf(this.queue,this.queue.length * 2);
}
this.queue[rear]=val;
this.rear++;}
2.出队列(判断队列是否为为空)
public int poll(){
if(q.empty()){
return -1;
}
this.front++;
return this.queue[this.front];
}
3.判断队列的空与满
public boolean empty(){ //空
return this.rear==this.front;
}
public boolean full(){ //满
return this.queue.length==this.rear;//队列的长度等于rear, rear指向有效元素的下一位
}
4.返回队头和队列长度元素
public int peek(){
return this.queue[this.front];
}
public int size(){
return this.rear-this.front;
}
class Queue{ // 存储队列的元素 private int[] queue; // 队头 private int front; // 队尾 private int rear; public Queue() { this(1); } // 自定义队列大小 public Queue(int size) { this.queue=new int[size]; this.front=0; int rear=0; } // 入队操作 public void offer(int val){ if(this.full()){ this.queue=Arrays.copyOf(this.queue,this.queue.length * 2); } this.queue[this.rear]=val; this.rear++; } // 出队,并把队头元素返回 public int poll(){ //先判断队列是否为空 if(empty()){ return -1; } this.front++;//先将队头向后移 return this.queue[this.front-1]; } // 查看队头元素 public int peek(){ return this.queue[this.front]; } //返回队列长度 public int size(){ return this.rear-this.front; } // 判断队满 public boolean full() { return this.rear== this.front; } // 判断队空 public boolean empty(){ return (this.front==this.rear); } public String toString() { String str=new String(); for(int i=0;i<this.rear;i++){ //i需要小于队尾指向的数据 str=str+this.queue[i]+" "; } return str; } } public class QueueTest { public static void main(String[] args) { Queue q =new Queue(); for(int i=0;i<10;i++){ q.offer(i+1); } System.out.println(q.toString()); q.offer(2); System.out.println(q); System.out.println(q.size()); System.out.println(q.peek()); while(!q.empty()){ System.out.print(q.poll()+" "); } } }
注:当有toString方法时,打印q或者q.toString都能输出队列输出的值;当没有toString方法时,打印q会打印出q的地址,因为q是一个引用变量。
练习3•:循环队列类
因为采用顺序栈存储数据时,当头指针和尾指针都指向队列的末尾时,即使队列前面是空的,也会因为被判断队满而无法继续存储,称为“假溢出”现象。因此人们便想出了循环队列的存储方式。
在循环队列中,指针和队列元素之间的关系不变。需要浪费一个内存单元来判断队列的满。队列满的条件:(rear+1)%n==head,队列空的条件:rear=front,用来区别于顺序队列。
方法:循环队列满
public boolean full(){
return (rear+1)%n==head;
}
class Queue{ // 存储队列的元素 private int[] queue; // 队头 private int front; // 队尾 private int rear; public Queue() { this(1); } // 自定义队列大小 public Queue(int size) { this.queue=new int[size]; this.front=0; int rear=0; } // 入队操作 public void offer(int val){ if(this.full()){ this.queue=Arrays.copyOf(this.queue,this.queue.length * 2); } this.queue[this.rear]=val; this.rear++; } // 出队,并把队头元素返回 public int poll(){ //先判断队列是否为空 if(empty()){ return -1; } this.front++;//先将队头向后移 return this.queue[this.front-1]; } // 查看队头元素 public int peek(){ return this.queue[this.front]; } //返回队列长度 public int size(){ return this.rear-this.front; } // 判断队满 public boolean full() { return (this.rear+1)%this.queue.length==this.front; } // 判断队空 public boolean empty(){ return (this.front==this.rear); } public String toString() { String str=new String(); for(int i=0;i<this.rear;i++){ str=str+this.queue[i]+" "; } return str; } } public class QueueTest { public static void main(String[] args) { Queue q =new Queue(); for(int i=0;i<10;i++){ q.offer(i+1); } System.out.println(q.toString()); q.offer(2); System.out.println(q); System.out.println(q.size()); System.out.println(q.peek()); while(!q.empty()){ System.out.print(q.poll()+" "); } } }
练习4•:栈
栈是一种先进后出的数据类型,后进先出:最后插入的元素最先出来
栈的属性:栈顶指针int top,数组长度int[] stack;
栈的方法:判断栈空、栈满 入栈、出栈
栈与队列的区别:
栈的相关方法 1.入栈
public void push(int val){
if(full()){
this.stack=Array.copyOf(this.array,this.stack.length*2);
}
array[top++]=val;
}
2.出栈,并返回出栈元素
public int pop(){
this.top--;
return this.stack[top];}
3.返回栈顶元素
public int top(){
return this.stack[top--];
}
4.判断栈空、栈满
public boolean empty(){return this.top==0;}
public boolean full(){return this.top==this.stack.length;}
5.返回元素个数
public int size(){return this.top;}
class SeqStack{ private int[] stack;// 存储栈元素的数组 private int top;// 标识栈顶的位置 // 默认构造,初始大小为10 public SeqStack() { this(10); } // 用户指定栈的初始大小 public SeqStack(int size) { this.stack=new int[size]; this.top=0;//当前栈中的元素个数 } // 入栈操作,把val值加入栈 public void push(int val){ if(full()){ this.stack=Arrays.copyOf(this.stack,this.stack.length * 2); } this.stack[this.top]=val; this.top++; } // 出栈,并把出栈的元素返回 public int pop() { this.top--; int val=this.stack[top]; return val; } // 返回栈顶元素 public int top(){ return this.stack[top-1]; } // 判断栈空 public boolean empty(){ return this.top==0; } // 判断栈满 public boolean full(){ return this.stack.length==this.top; } // 返回栈元素的个数 public int size(){ //判断栈中元素是否为空 return this.top; } // 自定义栈元素的打印方式 public String toString() { String str=new String(); for(int i=0;i<this.top;i++){ str=str+this.stack[i]+" "; } return str; } } public class SeqStackTest { public static void main(String[] args) { SeqStack s =new SeqStack(); for(int i=0;i<10;i++){ s.push(i+1); } System.out.println(s.size());//栈的长度 System.out.println(s.toString());//打印栈 System.out.println(s.top());//栈顶元素 while (!s.empty()){ System.out.print(s.pop() + " "); //逆序出栈 } System.out.println(); System.out.println(s.size()); //出完栈后栈的长度为0 } }