数组、数组操作、无序数组、有序数组、二分法

来源:互联网 发布:乘联会销量数据suv 编辑:程序博客网 时间:2024/05/21 19:49

数组、数组操作、无序数组、有序数组、二分法

什么是数组?

  • 数组是一个相同类型数据的集合,用来保存相同类型的数据,是一个引用类型。数组一旦创建,其大小不可改变。
  • 数组操作
  • 插入
  • 删除
  • 查找

有序数组

数组中存放的数据是按照某种规则排过顺序的。优点就是增加了查询的效率,但是它并没有提高删除和插入元素的效率,因此,对于有序数组更适合用于查询的领域。

二分法

二分法查找的前提是:你的这个数组是经过排序的,即时有序数组。
主要思想:假设被查找的数组为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.循环14,直到返回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

0 0