有序数组
----有序数组是一种特殊的数组,里面的元素,按一定的顺序排列,我们这里假设由小到大排列。有序数组的优点是增加了查询的效率,缺点是它并没有提高删除和插入元素的效率,因此,有序数组更适合用于查询的领域。
- 有序数组的增加是先移动后插入;
- 有序数组的删除是将先数据向前移动,在把数组长度减去一;
二分查找
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
- 可以用二分法对有序数组进行查找,提高效率;
- 二分查找的数据越多,效率就越高;
查找过程
- 首先,假设数组元素是按升序排列,将数组中间位置的数据与查找数据比较,如果两者相等,则查找成功;否则利用中间位置下标将数组分成前、后两个子数组,如果中间位置的数据大于查找数据,则进一步查找前一子数组,否则进一步查找后一子数组。重复以上过程,直到找到满足条件的数据,使查找成功,或直到子数组不存在为止,此时查找不成功。
算法要求
- 必须采用顺序存储结构。
- 必须按关键字大小有序排列。
比较次数
- 计算公式: a < log(2)n < b
- 当数组有n个数据时:
- 查找失败时,至少比较a次数据;查找成功时,最多比较数据次数是b。
- 注意:a,b,n均为正整数。
时间复杂度
- O(h)=O(log2n)
举例
创建一个OrdArray类,里面封装了使用二分查找和线性查找的方法:
package arrayapplication;
public class OrdArray {
private long[] arr;
private int nElems;
public OrdArray(int max){
arr = new long[max];
nElems = 0;
}
//返回数组长度
public int size(){
return nElems;
}
//删除
public boolean delete(long value){
int j = find(value);
if(j==nElems)
return false;
else{
for(int k = j; k < nElems ;k++)
arr[k]=arr[k+1];
nElems--;
}
return true;
}
//添加(线性查找)
public void insert(long value){
int j;
for(j=0;j<nElems;j++)
if(arr[j]>value) break;
for(int k = nElems; k>j ;k--)
arr[k]=arr[k-1];
arr[j]=value;
nElems++;
}
//查找(二分法)
public int find(long searchKey){
int lowerBound = 0; //最小下标
int upperBound = nElems;//最大下标
int curIn = 0;
//中间下标
while(true){
curIn = (lowerBound+upperBound)/2;
if(arr[curIn] == searchKey)
return curIn;
else if(lowerBound > upperBound)
return nElems;
else{
if(arr[curIn] < searchKey)
lowerBound = curIn+1; //往后查找
else
upperBound = curIn-1; //往前查找
}
}
}
//显示所有
public void display(){
for(int j = 0; j<nElems; j++){
System.out.print(arr[j]+" ");
}
System.out.println();
}
}
创建OrdArrayApp类,对OrdArray的方法进行实现:
package arrayapplication;
public class OrdArrayApp {
public static void main(String[] args){
OrdArray arr = new OrdArray(10);
long searchKey;
arr.insert(99);
arr.insert(98);
arr.insert(97);
arr.insert(96);
arr.insert(95);
arr.insert(94);
searchKey = 93;
arr.display();
if(arr.delete(searchKey))
System.out.println("Found:"+searchKey);
else
System.out.println("Can't find:"+searchKey);
arr.display();
}
}
下一篇记录存储对象的数组。