数组概念
数组是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。这里我们要抽取出三个跟数组相关的关键词:线性表,连续内存空间,相同数据类型;数组具有连续的内存空间,存储相同类型的数据,正是该特性使得数组具有一个特性:随机访问。但是有利有弊,这个特性虽然使得访问数组边得非常容易,但是也使得数组插入和删除操作会变得很低效,插入和删除数据后为了保证连续性,要做很多数据搬迁工作。
查找数组中的方法有两种:
- 线性查找:线性查找就是简单的查找数组中的元素
- 二分法查找:二分法查找要求目标数组必须是有序的。
无序数组
- 实现类:
public class MyArray {
//声明一个数组
private long[] arr;
//有效数据的长度
private int elements;
//无参构造函数,默认长度为50
public MyArray(){
arr = new long[50];
}
public MyArray(int maxsize){
arr = new long[maxsize];
}
//添加数据
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 long get(int index){
if(index >= elements || index < 0){
throw new ArrayIndexOutOfBoundsException();
}else{
return arr[index];
}
}
/**
* 根据值查询
* @param value 需要被查询的值
* @return 被查询值的下标
*/
public int search(int value){
//声明一个变量i用来记录该数据的下标值
int i ;
for(i = 0;i < elements;i++){
if(value == arr[i]){
break;
}
}
//如果查询到最后一个元素依然没有找到
if(i == elements){
return -1;
}else{
return i;
}
}
//根据下标删除数据
public void delete(int index){
if(index >= elements || index < 0){
throw new ArrayIndexOutOfBoundsException();
}else{
//删除该元素后,后面所有元素前移一位
for(int i = index; i < elements;i++){
arr[i] = arr[i+1];
}
elements--;
}
}
/**
* 替换数据
* @param index 被替换的下标
* @param newvalue 新的数据
*/
public void change(int index,int newvalue){
if(index >= elements || index < 0){
throw new ArrayIndexOutOfBoundsException();
}else{
arr[index] = newvalue;
}
}
}
- 优点:插入快(时间复杂度为:
O(1)
)、如果知道下标,可以很快存储 - 缺点:查询慢(时间复杂度为:
O(n)
)、删除慢
有序数组
- 实现类:
public class MyOrderArray {
private long[] arr;
private int elements;
public MyOrderArray(){
arr = new long[50];
}
public MyOrderArray(int maxsize){
arr = new long[maxsize];
}
//添加数据
public void insert(int 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++;
}
//删除数据
public void delete(int index){
if(index >=elements || index <0){
throw new ArrayIndexOutOfBoundsException();
}else{
for(int i = index;i < elements; i++){
arr[i] = arr[i+1];
}
elements--;
}
}
//修改数据
public void change(int index,int value){
if(index >= elements || index < 0){
throw new IndexOutOfBoundsException();
}else{
arr[index] = value;
}
}
//根据下标查询数据
public long get(int index){
if(index >= elements || index < 0){
throw new IndexOutOfBoundsException();
}else{
return arr[index];
}
}
//展示数据
public void display(){
System.out.print("[");
for(int i = 0; i < elements;i++){
System.out.print(arr[i] + " ");
}
System.out.println("]");
}
//二分法查找数据
public int binarySearch(long value){
//声明三个指针分别指向数组的头,尾,中间
int low = 0;
int pow = elements;
int middle = 0;
while(true){
middle = (low + pow) / 2;
//如果中指针所指的值等于带查询数
if(arr[middle] == value){
return middle;
}else if(low > pow){
return -1;
}else{
if(arr[middle] > value){
//待查询的数在左边,右指针重新改变指向
pow = middle-1;
}else{
//带查询的数在右边,左指针重新改变指向
low = middle +1;
}
}
}
}
}
- 优点:查询快(时间复杂度为:
O(logn)
) - 缺点:增删慢(时间复杂度为:
O(n)
)