数据结构与算法——数组的实现(Java)

数组是可以存储一组数据的数据类型,特点是逻辑相邻的数据在物理存储位置上也相邻。数组的存储大小在刚开始创建数组时已经定好,不可发生改变,所以当数组空间存满后,需要我们人为对它进行扩容,因为数组大小不可改变,这里的扩容其实是创建一个更大的新数组。

数组的特点还有查询快,但是向其中插入和删除较为费时,需要给待插入数据腾出位置,所以其后方的每一个元素都需要移动。因此如果插入位置在尾部,耗时最小,但是如果在首位,耗时最大。

	int[] arr;
	int size;
	int capacity;

首先定义三个变量,分别表示,存储数据的数组,数组已存数据的长度,整个数组的大小。在c语言中,我们需要使用malloc函数对数组进行分配空间,在java中可以直接new出来。

	Array array=new Array();

初始化操作

	public static void InitArray(Array array) {
	    array.arr=new int[8];
	    array.size=0;
	    array.capacity=8;
	}

创建好数组对象后,如c一样,我们需要先对数组进行初始化,将三个变量给定初始值。我一般喜欢将数组长度定义为8,那么capacity变量的值自然也是8,因为其中还没有存储数据,所以size的值是0。

插入操作

    public static boolean InsertArray(Array array,int index,int element){
        if (index<0||index>array.size+1){
            System.out.println("插入位置不合法");
            return false;
        }
        if(array.size==array.capacity){
        	int[] newcapacity=array.capacity*2;
            int[] newarray=new int[newcapacity];
            for(int i=0;i<array.size;i++){
				newarr[i]=arr[i];
			}
			array.arr=newarr;
			array.capacity=capacity;
        }
        for (int i=array.size;i>=index;i--){
            array.arr[i]=array.arr[i-1];
        }
        array.arr[index-1]=element;
        array.size++;
        return true;
    }

插入操作的返回值我将其定义为布尔型,意思是如果插入成功,则返回true,反之返回false。第一步自然还是判断插入位置是否合法,如果不合法,则直接返回false。接下来,就碰到了第一个问题,我们要向数组中插入新的元素,可是数组的大小已经确定,如果数组已经存满怎么办?我们需要判断是否数组是否已满,如果已满则需要对数组进行扩容。数组已满的条件是存储的元素数量和数组大小相等时,代表数组中所有空间都有元素存储了。这时我们就需要进行数组扩容。每次扩容将数组扩大为当前的两倍,第一次是从8扩容到16,第二次是从16扩容到32。首先定义一个新的数组大小的变量newcapacity是两倍的当前数组大小,再使用该大小定义一个新的大小的数组。将原来数组的每一个元素复制到新数组中,最后将新数组和新的数组大小代替旧的来使用,到此完成扩容。接下来就可以正式开始插入操作了,然后就面对了第二个问题,数组的特点是存储位置相邻,我们没有多余的位置插入新的元素,那么我们就需要将插入位置后方的元素依次向后移动,来给待插入的元素腾出位置。这里有一个需要特别注意的点,就像上学时站队一样,如果队伍前方突然出现一个人,为了让他进入队伍,我们需要向后移动给他腾出位置,但应该怎么移动呢?如果从前往后移动,后面的人没动,前面的人先向后移,则肯定会踩到后面的人,在数组中,这种情况就表现为,前面的数据会覆盖后面的数据。为了避免这种情况,需要从队尾开始移动,从后往前移动,先移后方的,后面的移动完成后,前面的才有空位向后移动。移动完成后,将插入位置的元素赋值完成插入。这里注意的是,我将index作为位序使用,而不是数组下标,位序是从1开始,而下标是从0开始。所以位序=数组下标+1。最后别忘了将数组存储长度加1,返回true,代表插入成功。

删除操作

    public static boolean DeleteArray(Array array,int index){
        if(index<1||index>array.size) {
            System.out.println("删除位置不合法");
            return false;
        }
        for (int i = index; i <array.size ; i++) {
            array.arr[i-1]=array.arr[i];
        }
        array.size--;
        return true;
    }

同插入操作一样,需要判断删除位置的合法性,需要移动元素来保证物理存储位置的相邻。删除中可以直接用删除元素的后继元素将其覆盖,然后后续元素依次前移,即可完成删除操作。

查找操作

    public static int FindArray(Array array,int element){
        for(int i=0;i< array.size;i++){
            if (array.arr[i]==element){
                return i+1;
            }
        }
        return -1;
    }

查找操作目的是为了查找数据是否存在数组中,如果存在,返回该元素第一个的位序,如果不存在,返回错误信息-1。这里采取的方法就是通过循环遍历数组中的每一个元素,与待查找的元素进行比较,如果相等,则可以返回位序=下标+1,如果循环结束,仍没有找到,代表数据不存在数组中,返回-1。

获取操作

	public static int GetArray(Array array,int index){
        return array.arr[index-1];
    }

获取操作的目的是,返回数组中指定位序的数据,注意下标和位序的关系即可。

获取长度

    public static int LengthArray(Array array){
        return array.size;
    }

有时我们需要用到数组中存取元素的数量,这里我们可以直接返回size。

打印数组

    public static void PrintArray(Array array){
        for (int i=0;i<array.size;i++) {
            System.out.print(array.arr[i]+" ");
        }
        System.out.println();
    }

每次操作完数组后,为了方便看到数组的情况,我们将其打印输出在控制台中。输出时,将数组中的所有元素输出在一行内,相邻元素之间使用空格分隔。当打印完成之后,别忘了换行方便下次打印输出。

完整代码

public class Array {
    int[] arr;
    int size;
    int capacity;

    public static void InitArray(Array array) {
        array.arr=new int[8];
        array.size=0;
        array.capacity=8;
    }

    public static boolean InsertArray(Array array,int index,int element){
        if (index<0||index>array.size+1){
            System.out.println("插入位置不合法");
            return false;
        }
        if(array.size==array.capacity){
            int[] newarray=new int[array.capacity*2];
            if (array.size >= 0) System.arraycopy(array.arr, 0, newarray, 0, array.size);
            array.arr=newarray;
            array.capacity=array.capacity*2;
        }
        for (int i=array.size;i>=index;i--){
            array.arr[i]=array.arr[i-1];
        }
        array.arr[index-1]=element;
        array.size++;
        return true;
    }

    public static boolean DeleteArray(Array array,int index){
        if(index<1||index>array.size) {
            System.out.println("删除位置不合法");
            return false;
        }
        for (int i = index; i <array.size ; i++) {
            array.arr[i-1]=array.arr[i];
        }
        array.size--;
        return true;
    }

    public static int FindArray(Array array,int element){
        for(int i=0;i< array.size;i++){
            if (array.arr[i]==element){
                return i+1;
            }
        }
        return -1;
    }

    public static int GetArray(Array array,int index){
        return array.arr[index-1];
    }

    public static int LengthArray(Array array){
        return array.size;
    }

    public static void PrintArray(Array array){
        for (int i=0;i<array.size;i++) {
            System.out.print(array.arr[i]+" ");
        }
        System.out.println();
    }

    public static void main(String[] args){
        Array array=new Array();
        InitArray(array);
        for(int i=0;i<13;i++){
            InsertArray(array,1,i*10);
        }
        PrintArray(array);
        InsertArray(array,8,666);
        PrintArray(array);
        DeleteArray(array,7);
        PrintArray(array);
        System.out.println(FindArray(array,60));
        System.out.println(FindArray(array,666));
        System.out.println(GetArray(array,5));
        System.out.println(LengthArray(array));
    }
}

其中的main函数中的操作属于数据测试,可以替换为自己需要的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值