线性表的实现(Array数组)

线性表

定义:

        线性表是一个有限的集合,寻找相同性质的数据元素,

特点:

        数据元素是有限的

        数据元素都是相同性质的、

        线性表中元素和序号是一 一对应的,一个序号对应一个元素,

逻辑结构:

        (a0,a1,a2…an-1) 相邻关系

        n  --> 元素的个数

        每个元素的唯一位置,通过下标索引来表示。

抽象数据类型 ADT:

        ADT  list{

        //二元组

        D = {ai | 0 <= i<=n-1,i = 0,1,2,3,4…n-1}   i是下标

        R = {<ai,ai+1> }   ai和ai +1 都属于D,i =0,1,2….n-2}

        }

图解:

注意:注意区分长度和容量两个的概念区别,不要混淆了。

线性表方法:

public SqList()   构造方法,实例化线性表对象,并准备数据

void createList(E[] e)    根据数组e创建线性表,

int  size(int a)     求线性表的长度,长度用size表示

void  setSize(int i)   设置线性表的长度设置为a

void updateCapactiy(int newCapacity)    实现数组容量的扩容和缩小

void add(E a)     添加一个元素a到线性表的末尾

void  insert(int i,E e)    将数据e插入到线性表中下标为i的位置

void  delete(int i)    删除线性表中下标为i的元素

void   swap(int I,int j )   将下标i和下标j的数据进行互换

E getElem(int i)    获取指定下标为i的元素

int getNo(E e)   获取线性表中第一个值e的下标

String toString()    将线性表的元素拼接成字符串并返回

注意:当元素快要溢出的时候,扩容需要进行2倍容量扩容。

线性表的顺序存储结构

实现:

        Array 数组实现

容量:

        数组的总空间,能存放的最大元素个数,

长度:

        size = 元素实际个数

最后元素:

        size -1

代码实现:(就是实现上面的那些线性表方法,div一个线性表)

package dataStruct;

import sun.net.www.content.text.plain;
import sun.tools.jar.resources.jar;

/*
 	顺序线性表的模拟(数组实现)
 */
public class SqList<E> { // 泛型类
	final int initCapacity = 10; // 数组的初始容量

	public E[] data;// 用来存储元素的数组data

	public int size; // 用来存储数组元素的个数

	public int capacity;// 用来表示数组的最大容量

	/*
	 * 构造方法 (实例化的时候创建一个数组)
	 */
	public SqList() { //
		// 创建数组
		data = (E[]) new Object[initCapacity];
		// 刚创建的线性表容量 = 初始容量
		capacity = initCapacity;
		// 刚开始是没有元素的,所以长度为0
		size = 0;
	}

	/*
	 * 实现数组容量的扩容和缩小
	 */
	private void updateCapacity(int newCapacity) {
		// 模仿数组扩容方式
		E[] newdata = (E[]) new Object[newCapacity];
		for (int i = 0; i < size; i++) { // 把元素转移到newdata
			newdata[i] = data[i];
		}
		// 更新容量
		capacity = newCapacity;
		// 更新数组元素
		data = newdata;
	}

	/*
	 * 根据指定数组创建线性表
	 */
	public void CreateList(E[] e) {
		int j = 0;
		// 将数组e的元素放图data数组里面,
		for (int i = 0; i < e.length; i++) {
			// 考虑会不会溢出,是否扩容
			if (size == capacity) { // size等于最大容量,说明需要进行扩容了
				updateCapacity(2 * size);
			}
			data[j] = e[i];
			// 纪录元素个数
			j++;
		}
		// 更新长度
		size = j;
	}

	/*
	 * 返回线性包的长度,大小
	 */
	public int size() {
		return size;
	}

	/*
	 * 添加元素至末尾 (size-1当前租后一个元素,所以我们添加就是size下标)
	 */
	public void add(E a) {
		if (size == capacity) {
			updateCapacity(2 * capacity);
		}
		// 添加末尾
		data[size] = a;
		// 更新长度
		size++;
	}

	/*
	 * 设置长度
	 */
	public void setSize(int a) {
		// 考虑长度a是否合理, 0<a <size
		if (a < 0 || a > size) {
			throw new IllegalArgumentException("长度不在有效范围内");
		}
		size = a;
	}

	/*
	 * 根据下标i获取元素
	 */
	public E GetElem(int i) {
		// 在有效范围内
		if (i < 0 || i >= size) {
			throw new IllegalArgumentException("下标不在有效范围内");
		}
		return (E) data[i];
	}

	/*
	 * 获取线性表中第一个值为e的下标
	 */
	public int getNo(E e) {
		// 使用for循环进行元素的比较, 遍历data数组,但是如果e不在数组里面,
		int i = 0; // 代表data元素序号
		while (i < size && !data[i].equals(e)) { // i< size 还没有找到e元素
			i++;
			break;
		}
		// 循环完了还是没找到,
		if (i == size) {
			return -1;
		}
		// 两个条件都满足,找到了
		return i;

	}

	/*
	 * 交换元素
	 */
	public void Swap(int i, int j) {
		if (i < 0 || i > size - 1 || j < 0 || j > size - 1) {
			throw new IllegalArgumentException("下标不在有效范围内!");

		}
		E temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

	/*
	 * 指定下标插入元素(下标为i后面的元素往后移动1位)
	 */
	public void insertElem(int i, E e) {
		// 判断下标i的范围是否合理
		if (i < 0 || i > size - 1) {
			throw new IllegalArgumentException("下标不在指定范围内");
		}
		// 判断容量是否足够
		if (i == size) {
			updateCapacity(2 * capacity);
		}
		// 从后往前移动
		for (int j = size; j > i; j--) {
			data[j] = data[j - 1]; // 移动1位
		}
		// 移动完指定位置就空出来了,直接赋值
		data[i] = e;
	}

	/*
	 * 删除元素(后面的值进行覆盖)
	 */
	public void Delete(int i) {
		// 下标是否合理
		if (i < 0 || i > size - 1) {
			throw new IllegalArgumentException("下标不在指定范围内");
		}
		for (int j = i; j < size - 1; j++) {
			data[j] = data[j + 1];// 覆盖
		}
		size--;
		// 如果删除到一定的数目,需要进行缩小容量 capacity 120 size = 1/4 capacity = 30, capacity = 60;
		// 四分之一,进行减容量到一半
		if (size == capacity / 4 && capacity > initCapacity) {// 同时满足大于初始容量
			updateCapacity(capacity / 2); // 减到一半
		}
	}

	/*
	 * 元素拼接成字符串返回
	 */
	public String toString() {
		String answar = "";
		for (int i = 0; i < data.length; i++) {
			answar += data[i];
		}
		return answar;
	}
}

注意:我们删除元素哪里进行判断减少线性表容量,是因为避免资源浪费。

实现调用:

现在我们就能直接使用这个我们自定义的线性表了,并实现里面的方法,

package dataStruct;

/*
 * 自定义线性表的实现
 */
public class SqList_Test {
	public static void main(String[] args) {
		// 实例化线性表对象
		SqList<Object> sqList = new SqList<>();

		// 根据指定数组实现创建线性表
		Object[] arr = { 1, 2, 3, 4, 5, 6 };
		sqList.CreateList(arr);

		// 返回线性表大小
		System.out.println(sqList.size());

		// 获取指定元素第一次出现的下标
		System.out.println(sqList.getNo(2));

		// 获取指定下标的元素
		System.out.println(sqList.GetElem(1));
	}
}

猜你喜欢

转载自blog.csdn.net/qq_53263466/article/details/123950858