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

本文详细介绍了数组的基本概念及其操作方法,包括插入、删除、查找等,并深入探讨了有序数组的优势及二分查找法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

什么是数组?

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

有序数组

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

二分法

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值