数据结构与算法---线性表---动态添加数组

一般数组在创建后,就决定了数组的大小,就不可以动态的再添加数组元素,而在实际应用中,我们希望这个数组是动态可以添加元素的。
当然,像iOS中会存在NSMutabbleArray这种类型
为了更好的了解动态数组的原理、特性,我们自己来实现一个动态数组

动态数组(Dynamic Array)接口设计

一个动态数组,应该包含一些接口:

int size();//获取元素的数量
bool isEmpty();//数组是否为空


//增删改查
void add(E element);//添加元素到数组最后面
void add(int index, E element);//在index位置添加元素

void remove(int index);//删除index位置上的元素
void clear();//删除所有元素

E set(int index, E element);//更新设置index位置的数据为element

bool contains(E element);//查找是否包含某个元素
E get(int index);//查找index的位置上对应的元素
int indexOf(E element);//查找某个元素所在的位置

一个数组的确定,至少需要两个变量:
在这里插入图片描述

int size;//表示数组的实际长度
int [] elements;//数组元素

对象数组

数组里面存放的是 对象(引用类型)

问:一个对象数组,里面的元素存储的是对象内容,还是地址?

比如,Person[] person = new Person[7];
那么,Person[0]里面存储的是什么?
假设Person里面有:
int age;//4
double height;//8
String name[];//4

如果Person[0]里面存储的是每一个实际变量
那也就是,每一个元素里面都有 age、height、name。那么每个元素至少要占16个字节
但是,由于建立数组的时候,是泛型建立的(这样才能保证数组里面放各种不同数据类型的数据),也就是:
Object[] objects = new Object[];
每个元素大小在建立的时候已经确定了,只有4个字节
那,后期怎么会自动扩容到16个字节?
因此,Person[0]里面存储的是地址

这样做也有好处,就是在初创数组的时候,即使写了new Object[7];,其实也只是7个引用的大小内存

在移除最后一个元素的时候,只需要将地址值赋值为null即可
在这里插入图片描述


动态数组的实现代码:

注:下面的代码接口名可能与上面的接口名不一样
上面是老师讲的时候的接口名
下面代码的接口名是自己默写的时候,自己想到的
该程序只支持类型为Int的数组,不支持对象数组、泛型等

package com.mj;

public class ArrayList {
	
	//元素的数量
	private int size;
	
	//所有元素
	private int[] elements;

有个需要注意的地方:
size是数组实际占用的大小
elements.length是数组分配的空间大小
size <= elements.length

	//构造函数
	public ArrayList()
	{
		elements = new int[10];
	}
	
	//带参的构造函数
	public ArrayList(int capaticy)
	{
		//防止用户输入不正确数字
		capaticy = capaticy < 10 ? 10 : capaticy;
		elements = new int[capaticy];
	}
	
	/**
	 *获取数组长度 
	 */
	public int size()
	{
		return size;
	}
	
	/**
	 *数组是否为空 
	 */
	public boolean isEmpty()
	{
		return size == 0;
	}
	
	
	/**
	 * 在数组最后面添加一个元素
	 */
	public boolean add(int element)
	{
		add(size, element);
		return true;
	}
	
	/**
	 * 在location位置上添加element元素,并返回老位置上的数据。这个应该理解为替换,而不是插入
	 * @param location
	 * @param element
	 */
	public int replace(int location, int element)
	{
		if (location < 0 || location >= size)
		{
			throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
		}
		
		int old = elements[location];
		elements[location] = element;
		return old;
	}
	
	/**
	 * 在location位置上添加element元素
	 * @param location
	 * @param element
	 */
	public void add(int location, int element)
	{
		if (location < 0 || location > size)
		{
			throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
		}
		
		ensureCapacity(size + 1);
		
		for (int i = size - 1; i >= location; i--) {
			elements[i+1] = elements[i];
		}
		elements[location] = element;
		size++;
	}
	
	/**
	 * 扩容
	 * */
	private void ensureCapacity(int capacity)
	{
		int oldCapacity = elements.length;
		if (oldCapacity >= capacity) {
			return;
		}
		
		int newCapacity = (int)(oldCapacity * 1.5);
		//或者
		//int newCapacity = oldCapacity + (oldCapacity >> 1);
		int[] newElements = new int[newCapacity];
		for (int i = 0; i < size; i++) {
			newElements[i] = elements[i];
		}
		elements = newElements;
	}
	
	/**
	 * 删除一个元素,并返回被删除的元素值
	 */
	public int delete()
	{
		size--;
		return 0;
	}
	
	/**
	 * 删除location位置上的元素,并返回被删除的元素值
	 */
	public int deleteArray(int location)
	{
		if (location < 0 || location >= size)
		{
			throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
		}
		//0 1 2 3 4  5  6 下标
		//2 4 6 7 9 10 12 数据
		//删除下标为3的值
		int old = elements[location];
		for (int i = location; i < size; i++) {
			elements[i] = elements[i + 1]; 
		}
		size--;
		//最后一个元素不处理也可以
		elements[size] = 0;
		return old; 
	}
	
	
	/**
	 * 查找location位置上的元素
	 */
	public int searchElementArray(int location)
	{
		if (location < 0 || location >= size)
		{
			throw new IndexOutOfBoundsException("您输入的数据有误: Index:"+location+" size:"+size);
		}
		
		return elements[location];
	}
	
	/**
	 * 查找element元素所在的位置
	 */
	public int searchContainsArray(int element)
	{
		for (int i = 0; i < size; i++) {
			if(elements[i] == element)
			{
				return i;
			}
		}
		System.out.println("没有找到该元素");
		return -1;
	}
	

	/**
	 * 数组清空,所有数组元素为0
	 */
	public void clearArray()
	{
		for (int i = 0; i < size; i++) {
			elements[i] = 0;
		}
		size = 0;
	}
	
	/**
	 * 销毁数组,数组不存在
	 */
	public void destroyArray()
	{
		size = 0;
	}
	
	//数组打印输出
	@Override
	public String toString()
	{
		StringBuilder string = new StringBuilder();
		string.append("size = ").append(size).append(" [");
		for (int i = 0; i < size; i++) {
			string.append(elements[i]);
			//不是最后一个元素才会加逗号(最后一个元素不加逗号)
			if (i != size-1) {
				string.append(", ");
			}
		}
		
		string.append("];");
		return string.toString();
	}
}

package com.mj;

public class Main {

	public static void main(String[] args)
    {
        ArrayList list = new ArrayList(2);
        int listLength = list.size();
        System.out.println("数组长度为" + listLength);
        
        list.add(2);
        list.add(22);
        list.add(32);
        list.add(3, 100);
        list.searchElementArray(1);
        list.add(2);
        System.out.println(list.toString());
        list.deleteArray(3);
        System.out.println(list.toString());
    }
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值