一.数组
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;
}
}
}
}