数组、数组操作、无序数组、有序数组、二分法
什么是数组?
- 数组是一个相同类型数据的集合,用来保存相同类型的数据,是一个引用类型。数组一旦创建,其大小不可改变。
- 数组操作
- 插入
- 删除
- 查找
有序数组
数组中存放的数据是按照某种规则排过顺序的。优点就是增加了查询的效率,但是它并没有提高删除和插入元素的效率,因此,对于有序数组更适合用于查询的领域。
二分法
二分法查找的前提是:你的这个数组是经过排序的,即时有序数组。
主要思想:假设被查找的数组为array[lowIndex,highIndex],要查找的数据为T,假设数组为升序的。
步骤:
1.获取array的中间位置k=(lowIndex+highIndex)/2,将T与数组array在中间位置的数据array[k]进行比较
2.若T==array[k],则返回k值
3.若T>array[k],则重新确定的数组的搜索区间为array[k+1,highIndex]
4.若T<array[k],则重新确定的数组的搜索区间为array[lowIndex,k-1]
5.循环1到4,直到返回T的下标。每一次查找与中间值比较,可以确定是否查找成功,不成功当前查找区间缩小一半。递归找,即可,时间复杂度:O(log2n)。
下面是普通数组的操作,使用下标来操作数组
public class AccessArrayByIndex {
private int[] datas = null;
private int currentIndex = 0;
public AccessArrayByIndex(int length)
{
datas = new int[length];
}
/**
* 返回数组中元素的数量
* @return
*/
public int size()
{
return currentIndex;
}
/**
* **新增一个元素,返回该元素在数组中的位置下标**
* @param data
* @return
*/
public int add(int data)
{
datas[currentIndex] = data;
currentIndex++;
//当数组中元素的数量超过数组长度的0.75时,就扩容
if(currentIndex > datas.length*0.75)
{
ensureCapacity();
}
return currentIndex-1;
}
/**
* 当数组中元素的数量超过数组长度的0.75时,就扩容
*/
private void ensureCapacity()
{
int[] newDatas = null;
newDatas = new int[currentIndex * 2 + 1];
System.arraycopy(datas, 0, newDatas, 0, currentIndex);
datas = newDatas;
}
/**
* 获取指定位置下标的元素
* @param index
* @return
*/
public int get(int index)
{
if(index < 0|| index > datas.length)
throw new IndexOutOfBoundsException();
return datas[index];
}
/**
* **删除指定位置下标的元素**
* @param index
* @return
*/
public void remove(int index)
{
if(index < 0|| index > datas.length)
throw new IndexOutOfBoundsException();
//1.将从index到currentIndex之间的元素向前移动一位
for(int i=index;i<currentIndex;i++)
{
datas[i] = datas[i+1];
}
currentIndex --;
}
public void print()
{
for(int i:datas)
{
System.out.print(i +" ");
}
}
public static void main(String[] args) {
AccessArrayByIndex array = new AccessArrayByIndex(10);
array.add(0);
array.add(1);
array.add(2);
array.add(3);
array.add(4);
array.add(5);
array.add(6);
array.add(7);
array.add(8);
array.add(9);
array.print();
System.out.println();
array.remove(1);
array.print();
}
}
控制台打印输出:
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0
0 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0
下面是不使用下标操作数组
public class AccessArrayNoByIndex {
private int[] datas ;
private int currentIndex;
public AccessArrayNoByIndex(int length)
{
datas = new int[length];
}
/**
* 新增一个元素,返回该元素在数组中的位置下标
* @param data
* @return
*/
public int add(int data)
{
datas[currentIndex] = data;
currentIndex++;
//当数组中元素的数量超过数组长度的0.75时,就扩容
if(currentIndex > datas.length*0.75)
{
ensureCapacity();
}
return currentIndex-1;
}
/**
* 当数组中元素的数量超过数组长度的0.75时,就扩容
*/
private void ensureCapacity()
{
int[] newDatas = null;
newDatas = new int[currentIndex * 2 + 1];
System.arraycopy(datas, 0, newDatas, 0, currentIndex);
datas = newDatas;
}
/**
* 获取指定元素的下标
* @param index
* @return
*/
public int get(int data)
{
int i ;
for(i=0;i<currentIndex;i++)
{
if(data == datas[i])
{
return i;
}
}
//代码走到这,说明data元素不存在数组datas中
return -1;
}
/**
* **删除某个元素**
* @param index
* @return
*/
public void remove(int data)
{
//1.查找data对应的索引
int index = get(data);
//只有当存在该元素的时候才进行删除操作
if(index >= 0)
{
//2.删除对应索引上的元素
for(int i=index;i<currentIndex;i++)
{
datas[i]=datas[i+1];
}
currentIndex--;
}
}
public void print()
{
for(int i:datas)
{
System.out.print(i +" ");
}
}
public static void main(String[] args) {
AccessArrayNoByIndex array = new AccessArrayNoByIndex(10);
array.add(2);
array.add(5);
array.add(1);
array.add(7);
array.add(8);
array.add(6);
array.add(2);
array.add(5);
array.add(1);
array.add(7);
array.add(8);
array.add(6);
array.print();
System.out.println();
System.out.println(array.get(5));
array.remove(1);
array.print();
}
}
控制台输出:
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0
0 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0
用数组存储可重复的数据
public class AccessArrayNoByIndexRepeatable {
private int[] datas ;
private int currentIndex;
public AccessArrayNoByIndexRepeatable(int length)
{
datas = new int[length];
}
/**
* 新增一个元素,返回该元素在数组中的位置下标
* @param data
* @return
*/
public int add(int data)
{
datas[currentIndex] = data;
currentIndex++;
//当数组中元素的数量超过数组长度的0.75时,就扩容
if(currentIndex > datas.length*0.75)
{
ensureCapacity();
}
return currentIndex-1;
}
/**
* 当数组中元素的数量超过数组长度的0.75时,就扩容
*/
private void ensureCapacity()
{
int[] newDatas = null;
newDatas = new int[currentIndex * 2 + 1];
System.arraycopy(datas, 0, newDatas, 0, currentIndex);
datas = newDatas;
}
/**
* 从指定下标index往后,获取元素data的第一个下标
* @param index
* @return
*/
public int get(int index,int data)
{
int i ;
for(i=index;i<currentIndex;i++)
{
if(data == datas[i])
{
return i;
}
}
//说明data元素不存在数组datas中
return -1;
}
/**
** 删除某个元素,若存在多个重复的元素则一起删除*
* @param index
* @return
*/
public void remove(int data)
{
int index = get(0,data);
//**当index != -1说明data在 index到currentIndex之间是有数据的**
while(index >= 0)
{
for(int i= index;i<currentIndex;i++)
{
datas[i] =datas[i+1];
}
currentIndex --;
index = get(index,data);
}
}
public void print()
{
for(int i:datas)
{
System.out.print(i +" ");
}
}
public static void main(String[] args) {
AccessArrayNoByIndexRepeatable array = new AccessArrayNoByIndexRepeatable(10);
array.add(2);
array.add(5);
array.add(1);
array.add(7);
array.add(1);
array.add(8);
array.add(6);
array.add(8);
array.print();
System.out.println();
array.remove(1);
array.print();
array.remove(8);
System.out.println();
array.print();
array.remove(6);
System.out.println();
array.print();
}
}
控制台输出:
2 5 1 7 1 8 6 8 0 0 0 0 0 0 0 0 0
2 5 7 8 6 8 0 0 0 0 0 0 0 0 0 0 0
2 5 7 6 0 0 0 0 0 0 0 0 0 0 0 0 0
2 5 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0
下面是有序数组的操作:
public class AccessOrderedArrayNoByIndexRepeatable {
private int[] datas ;
private int currentIndex;
public AccessOrderedArrayNoByIndexRepeatable(int length)
{
datas = new int[length];
}
/**
* 新增一个元素,返回该元素在数组中的位置下标
* @param data
* @return
*/
public int add(int data)
{
//假设数组是升序的
//1.获取data在数组中的下标index
int index ;
for(index =0;index<currentIndex;index++)
{
if(datas[index]>data)
break;
}
//2.从index到currentIndex的元素都往后移动一位
for(int i=currentIndex;i>index;i--)
{
datas[i] = datas[i-1];
}
//3.设置data到index位置
datas[index] = data;
currentIndex++;
return currentIndex-1;
}
/**
* 从指定下标index往后,获取元素data的第一个下标
* @param index
* @return
*/
public int get(int index,int data)
{
int i ;
for(i=index;i<currentIndex;i++)
{
if(data == datas[i])
{
break;
}
}
//说明data元素不存在数组datas中
if(i==currentIndex)
{
return -1;
}
return i;
}
/**
* 删除某个元素,若存在多个重复的元素则一起删除
* @param index
* @return
*/
public void remove(int data)
{
//首先获取index从0开始的下标
int index = get(0,data);
//当index != -1说明data在 index到currentIndex之间是有数据的
while(index >= 0)
{
for(int i= index;i<currentIndex;i++)
{
datas[i] =datas[i+1];
}
currentIndex --;
//重新获取开始位置为index的下一次下标
index = get(index,data);
}
}
public void print()
{
for(int i:datas)
{
System.out.print(i +" ");
}
}
public static void main(String[] args) {
AccessOrderedArrayNoByIndexRepeatable array = new AccessOrderedArrayNoByIndexRepeatable(10);
array.add(2);
array.add(5);
array.add(1);
array.add(7);
array.add(1);
array.add(8);
array.add(6);
array.add(8);
array.print();
System.out.println();
array.remove(1);
array.print();
array.remove(8);
System.out.println();
array.print();
array.remove(6);
System.out.println();
array.print();
}
}
控制台输出:
1 1 2 5 6 7 8 8 0 0
2 5 6 7 8 8 0 0 0 0
2 5 6 7 0 0 0 0 0 0
2 5 7 0 0 0 0 0 0 0
使用二分法的有序数组:
public class BinarySearchArray {
private int[] datas =null;
private int currentIndex = 0;
public BinarySearchArray(int length) {
datas = new int[length];
}
```java
/**
* 新增一个元素,返回该元素在数组中的位置下标
* @param data
* @return
*/
public int add(int data)
{
//假设是该数组是升序的
//1.获取要插入位置的下标index
int index ;
for(index=0;index<currentIndex;index++)
{
if(datas[index] > data)
break;
}
//2.将从下标index开始到currentIndex之间元素向后移动一位
//注意:这里是从后往前挪动
for(int i= currentIndex;i>index;i--)
{
datas[i]=datas[i-1];
}
//3.将元素data设置到index位置
datas[index] = data;
currentIndex++;
return index;
}
```
public void remove(int data)
{
//1.获取data在数组中下标index
int index = binarySearch(data);
//2.从index开始到currentIndex的元素都向前移动一位
for(int i=index;i<currentIndex;i++)
{
datas[i] = datas[i+1];
}
currentIndex --;
}
/**
* 获取指定元素在数组中的下标,用二分法查找
* @param data
* @return
*/
public int binarySearch(int data)
{
int index =-1;
//用来表示低位索引
int lowIndex = 0;
//用来表示高位索引
int highIndex = currentIndex-1;
while(true)
{
index =(lowIndex + highIndex)/2;
//说明没有找到元素
if(lowIndex > highIndex ){
return -1;
}
else if(data == datas[index])
{
return index;
}else
{
if(data < datas[index])
{
highIndex = index -1;
}else
{
lowIndex = index + 1;
}
}
}
}
public void print()
{
for(int i=0;i<currentIndex;i++)
System.out.print(datas[i]+" ");
}
public static void main(String[] args) {
BinarySearchArray array = new BinarySearchArray(10);
array.add(2);
array.add(5);
array.add(1);
array.add(4);
array.add(6);
array.add(8);
array.add(0);
array.add(9);
array.print();
array.remove(6);
System.out.println();
array.print();
}
}
控制台输出:
0 1 2 4 5 6 8 9
0 1 2 4 5 8 9