資料結構(二)——線性結構之陣列
阿新 • • 發佈:2018-12-31
一.陣列
1.陣列是典型的順序儲存結構。
2.陣列的基本使用
(1)建立一個數組
// 建立一個數組--三種方式
// 第一種:只指定陣列大小,不賦值。如果沒有賦值,每個元素都是0
int a[] = new int[3];
// 第二種和第三種,建立陣列的同時賦值
int b[] = {1, 2, 3, 4};
int c[] = new int[]{7, 8, 9};
(2)陣列的長度
// 陣列的長度(一共可以放多少元素)
int aLength = a.length;
(3)獲取陣列中的元素
// 獲取陣列中的元素,使用方式:陣列名[下標] 下標從0開始,最大可以取到(陣列的長度-1) int a0 = a[0];
(4)陣列元素賦值
// 陣列元素賦值
a[0] = 111;
(5)遍歷陣列
// 遍歷陣列
for (int i = 0; i < b.length; i++) {
System.out.println(b[i]);
}
(6)快速檢視陣列中的元素
// 快速檢視陣列中的元素
System.out.println(Arrays.toString(a));
(7)增加陣列元素
package cn.kimtian.array.one; import java.util.Arrays; /** * 由於陣列的長度是不可變的,那麼想為陣列增加元素就需要進行: * 1.新建另一個數組 * 2.把原陣列中的元素複製到新陣列中 * 3.把新增加的元素加入新陣列的最後 * 4.使用新陣列替換原有陣列 * * @author kimtian */ public class OptionArrayAdd { public static void main(String[] args) { /** * 陣列的長度是不可變的,如下面就指定了陣列a的長度為5 */ int a[] = new int[]{1, 2, 3, 4, 5}; // 快速檢視陣列中的元素 System.out.println("原來的陣列:" + Arrays.toString(a)); //要新加的元素 int addNum = 9; // 建立一個新的陣列,長度是原陣列長度+1 int newA[] = new int[a.length + 1]; // 把原陣列中的元素複製到新陣列中 for (int i = 0; i < a.length; i++) { newA[i] = a[i]; } // 把目標元素放入新陣列的最後 newA[newA.length - 1] = addNum; // 新陣列替換原資料 a = newA; System.out.println("現在的陣列:" + Arrays.toString(a)); } }
(8)刪除陣列元素
package cn.kimtian.array.one; import java.util.Arrays; /** * 由於陣列的長度是不可變的,那麼想為陣列刪除元素就需要進行: * 1.新建另一個數組 * 2.把原陣列中的不需要刪除的元素複製到新陣列中 * 3.使用新陣列替換原有陣列 * * @author kimtian */ public class OptionArrayDelete { public static void main(String[] args) { /** * 陣列的長度是不可變的,如下面就指定了陣列a的長度為5 */ int[] a = new int[]{1, 2, 3, 4, 5, 7, 9}; // 快速檢視陣列中的元素 System.out.println("原來的陣列:" + Arrays.toString(a)); //要刪除的元素的下標 int deleteNum = 2; // 建立一個新的陣列,長度是原陣列長度-1 int[] newA = new int[a.length - 1]; // 把原陣列中的除了要刪除的元素的其他元素複製到新陣列中 for (int i = 0; i < newA.length; i++) { //當前遍歷下標小於要刪除元素的下標 if (i < deleteNum) { newA[i] = a[i]; } // 要刪除的元素之後的元素 else { newA[i] = a[i + 1]; } } // 新陣列替換原資料 a = newA; System.out.println("現在的陣列:" + Arrays.toString(a)); } }
3.查詢演算法
(1)線性查詢
按陣列順序,將每一個元素對比一次,直到查詢到目標元素。
/**
* 這是陣列的線性查詢
*
* @author kimtian
*/
public class TestLinearSearch {
public static void main(String[] args) {
//目標陣列
int[] arrOne = new int[]{1, 2, 3, 4, 5, 6};
//目標元素
int targetNum = 5;
//目標元素所在的下標
int index = -1;
//遍歷陣列
for (int i = 0; i < arrOne.length; i++) {
if (arrOne[i] == targetNum) {
index = i;
//找到則停止,不繼續迴圈
break;
}
}
System.out.println("目標元素所在下標為:" + index);
}
}
(2)二分法查詢
將陣列一分為二,比較最中間的數,判斷大小,在選擇左部分和右部分,再依此迴圈查詢,直到找到為止。
要求陣列必須是有序的。
/**
* 這是陣列的二分查詢
*
* @author kimtian
*/
public class TestDichotomySearch {
public static void main(String[] args) {
//目標陣列
int[] arrTwo = new int[]{1, 2, 3, 4, 5, 6, 10, 23, 45, 67};
//目標元素
int targetNum = 10;
//記錄開始位置
int begin = 0;
//記錄結束位置
int end = arrTwo.length - 1;
//記錄中間位置
int mid = (begin + end) / 2;
//記錄目標位置
int index = -1;
//迴圈查詢
while (true) {
//判斷中間的元素是不是要查詢的元素
if (arrTwo[mid] == targetNum) {
index = mid;
break;
}
//中間這個元素不是要查的元素
else {
// 判斷中間這個元素是不是比目標元素大
if (arrTwo[mid] > targetNum) {
end = mid - 1;
} else {
begin = mid + 1;
}
mid = (begin + end) / 2;
}
}
System.out.println("目標元素所在下標為:" + index);
}
}
4.面向物件的陣列
建立一個面向物件的陣列,並對其封裝了以下操作。
(1)獲取陣列長度;
(2)往陣列新增元素;
(3)列印所有元素到控制檯;
(4)刪除陣列中的元素;
(5)往陣列中插入元素到指定位置;
(6)獲取某個下標的元素;
(7)替換指定位置的元素;
(8)線性查詢;
(9)二分法查詢。
package cn.kimtian.array.one;
import java.util.Arrays;
/**
* 建立一個面向物件的可見陣列
* 並對其進行操作
*
* @author kimtian
*/
public class MyArray {
/**
* 目標陣列,用於儲存資料的陣列
**/
private int[] elements;
public MyArray() {
elements = new int[0];
}
/**
* /獲取陣列長度的方法
*
* @return int 陣列的長度
*/
public int size() {
return elements.length;
}
/**
* 往陣列的末尾新增一個元素
*
* @param element 要新增的元素
*/
public void add(int element) {
// 建立一個新的陣列
int[] newArr = new int[elements.length + 1];
// 把原陣列中的元素複製到新的陣列中
for (int i = 0; i < elements.length; i++) {
newArr[i] = elements[i];
}
// 把新增的元素放入新陣列中
newArr[elements.length] = element;
// 使用新陣列替換老陣列
elements = newArr;
}
/**
* 列印所有元素到控制檯
*/
public void printToConsole() {
System.out.println(Arrays.toString(elements));
}
/**
* 刪除陣列中的元素
*
* @param index 刪除的下標
*/
public void delete(int index) {
//如果下標<0,或者大於最大邊界了(最大的下標為陣列的長度-1)
if (index < 0 || index > elements.length - 1) {
throw new RuntimeException("下標越界");
}
// 建立一個新的陣列
int[] newArr = new int[elements.length - 1];
// 把原陣列中的元素複製到新的陣列中
for (int i = 0; i < newArr.length; i++) {
//當前遍歷下標小於要刪除元素的下標
if (i < index) {
newArr[i] = elements[i];
}
// 要刪除的元素之後的元素
else {
newArr[i] = elements[i + 1];
}
}
// 使用新陣列替換老陣列
elements = newArr;
}
/**
* 往陣列中插入元素到指定位置
*
* @param index 插入的位置
* @param element 插入的值
*/
public void insert(int element, int index) {
//如果下標<0,或者大於最大邊界了(最大的下標為陣列的長度-1)
if (index < 0 || index > elements.length) {
throw new RuntimeException("下標越界");
}
// 建立一個新的陣列
int[] newArr = new int[elements.length + 1];
// 把原陣列中的元素複製到新的陣列中
for (int i = 0; i < elements.length + 1; i++) {
// 目標位置之前的元素
if (i < index) {
newArr[i] = elements[i];
}
//目標位置的元素
else if (i == index) {
newArr[i] = element;
}// 目標位置之後的元素
else {
newArr[i] = elements[i - 1];
}
}
// 使用新陣列替換老陣列
elements = newArr;
}
/**
* 獲取某個下標的元素
*
* @param index 下標數
*/
public int get(int index) {
if (index < 0 || index > elements.length - 1) {
throw new RuntimeException("下標越界");
} else {
return elements[index];
}
}
/**
* 替換指定位置的元素
*
* @param element 替換值
* @param index 下標數
*/
public void setIndexElement(int index, int element) {
// 判斷下標是否合法
if (index < 0 || index > elements.length - 1) {
throw new RuntimeException("下標越界");
}
elements[index] = element;
}
/**
* 線性查詢
*
* @param target 要查詢的目標數字
*/
public int linesrSearch(int target) {
//遍歷陣列
for (int i = 0; i < elements.length; i++) {
if (elements[i] == target) {
return i;
}
}
return -1;
}
/**
* 二分法查詢
*
* @param target 要查詢的目標數字
*/
public int dichotomySearch(int target) {
//記錄開始位置
int begin = 0;
//記錄結束位置
int end = elements.length - 1;
//記錄中間位置
int mid = (begin + end) / 2;
//迴圈查詢
while (true) {
//如果開始和結束元素相等,且不等於目標元素,則結束迴圈
if (begin == end && begin != target) {
return -1;
}
//判斷中間的元素是不是要查詢的元素
if (elements[mid] == target) {
return mid;
}
//中間這個元素不是要查的元素
else {
// 判斷中間這個元素是不是比目標元素大
if (elements[mid] > target) {
end = mid - 1;
} else {
begin = mid + 1;
}
mid = (begin + end) / 2;
}
}
}
}