數組是一種常用的數據結構,數組具有不可變性,創建後的數組的長度固定,通過索引訪問數組中的元素,訪問速度快,刪除添加效率低。
通過面向對象模擬數組,模擬的數組具有以下功能:
- 添加新元素
- 展示
- 查找元素所在位置
- 根據索引獲取元素
- 根據索引刪除元素
- 修改指定位置的元素
同時使用兩個算法對數組進行操作:
- 有序添加元素
- 二分查找法
1.創建數組類 MyArray.java
數據如何存儲呢?在類中添加一個數組類型的私有屬性用來保存數據,同時添加一個變量存儲有效數據的長度(也就是元素的個數)
創建數組的時候需要指定數組的長度,所以要添加兩個構造方法:
1.無參構造方法設置數組默認長度
2.有參構造方法指定數組長度
public class MyArray {
//存儲元素
private long[] arr;
//表示有效數據的長度
private int elements;
//無參構造默認50個長度
public MyArray() {
arr=new long[50];
}
public MyArray(int maxsize) {
arr=new long[maxsize];
}
}
2.編寫添加數據的方法
elements 屬性的默認值是 0,第一次向對象中添加元素也是添加到索引爲0 的元素中,添加後將 elements 的長度加1,就能一直向數組中添加元素了,添加元素的個數取決於 arr 的長度。
public void insert(long value) {
arr[elements]=value;
elements++;
}
3.編寫展示數據的方法
簡單的展示數組中的元素即可,使用 for 循環遍歷
public void display() {
System.out.print("[");
for (int i = 0; i < elements; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("]");
}
4.編寫查找數據的方法
思路:使用循環遍歷數組 arr ,將要查找的數據和 arr 中每個元素進行比較。如果相等,則跳出循環。循環結束後,如果循環次數等於元素個數說明沒有找到數據,返回-1。否則返回循環次數(即找到的索引)。
public int search(long value) {
int i ;
for (i = 0; i < elements; i++) {
if(value==arr[i]) {
break;
}
}
//遍歷到末尾說明沒有找到
if (i==elements) {
return -1;
}else {
return i;
}
}
5.根據索引獲取元素
思路:這相對比較簡單了,直接給 arr 索引就能獲取到元素。但是要注意傳入的索引必須可用,不能用的索引可以拋出異常。
public long get(int index) {
//如果索引大於可用,或索引小於0 都是無效的索引
if (index>=elements||index<0) {
//拋出數組越界異常
throw new ArrayIndexOutOfBoundsException();
}else {
return arr[index];
}
}
6.根據索引刪除元素
思路:和獲取元素時一樣,先檢查索引是否可用。如果可用,就從要刪除元素的位置開始向後遍歷,每次都將下一個元素的值賦值給當前元素。也就相當於要刪除的元素被下一個元素覆蓋,下一個元素被下下一個元素覆蓋,以此類推。元素移動完成後,將可用元素長度 elements 減1。
public void delete(int index) {
//如果索引大於可用,或索引小於0 都是無效的索引
if (index>=elements||index<0) {
throw new ArrayIndexOutOfBoundsException();
}else {
for(int i=index;i<elements;i++) {
arr[index]=arr[i+1];
}
elements--;
}
}
7.修改指定位置的元素
思路:和獲取差不多,就是把獲取改爲修改
public void change(int index,int newValue) {
//如果索引大於可用,或索引小於0 都是無效的索引
if (index>=elements||index<0) {
throw new ArrayIndexOutOfBoundsException();
}else {
arr[index]=newValue;
}
}
8.完整代碼
public class MyArray {
private long[] arr;
//表示有效數據的長度
private int elements;
public MyArray() {
arr=new long[50];
}
public MyArray(int maxsize) {
arr=new long[maxsize];
}
/**
* 添加數據
* @param value
*/
public void insert(long value) {
arr[elements]=value;
elements++;
}
/**
* 顯示數據
*/
public void display() {
System.out.print("[");
for (int i = 0; i < elements; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("]");
}
/**
* 查找數據
*/
public int search(long value) {
int i ;
for (i = 0; i < elements; i++) {
if(value==arr[i]) {
break;
}
}
//遍歷到末尾說明沒有找到
if (i==elements) {
return -1;
}else {
return i;
}
}
/**
* 查找數據,根據索引來查
*/
public long get(int index) {
//如果索引大於可用,或索引小於0 都是無效的索引
if (index>=elements||index<0) {
throw new ArrayIndexOutOfBoundsException();
}else {
return arr[index];
}
}
/**
* 刪除數據
*/
public void delete(int index) {
//如果索引大於可用,或索引小於0 都是無效的索引
if (index>=elements||index<0) {
throw new ArrayIndexOutOfBoundsException();
}else {
for(int i=index;i<elements;i++) {
arr[index]=arr[i+1];
}
elements--;
}
}
/**
* 更新數據
*/
public void change(int index,int newValue) {
//如果索引大於可用,或索引小於0 都是無效的索引
if (index>=elements||index<0) {
throw new ArrayIndexOutOfBoundsException();
}else {
arr[index]=newValue;
}
}
}
9.有序添加元素
思路:修改 insert 方法,遍歷 arr 數組,如果當前元素大於添加的數據,當前的位置就要存入的位置。從最後一個元素開始,逐個將元素向後位移,空出要存入的位置。存入要添加的元素後,將有效數據長度加1。
public void insert(long value) {
int i;
for(i=0;i<elements;i++) {
if(arr[i]>value) {
break;
}
}
for (int j = elements; j > i; j--) {
arr[j]=arr[j-1];
}
arr[i]=value;
elements++;
}
10.二分查找法
思路:數據必須是有序的,才能使用二分查找法!可以結合有序添加元素一塊使用,這裏的序列是升序(從小到大)。二分查找是每次和一組數中間的數進行比較,如果大於就再和右邊的數最中間的數比較,如果小於就和左邊的數最中間的數比較。直到中間的數和要查找的數相等,否則就是沒有這個數。
public int binarySearch(long value) {
int mid=0;//中間值
int low=0;
int high = elements;
while(true) {
mid=(high+low)/2;
if(arr[mid]==value) {
return mid;
}else if(low>high) {
return -1;
}else {
if (value>arr[mid]) {
high=mid+1;
}else {
high=mid-1;
}
}
}
}