线性表-顺序实现

终于进入正题了,这一章介绍线性表,既然说到线性表,就要先谈一下什么叫线性,线性结构主要有以下几个特点

  1. 存在唯一的一个被称作第一个的元素
  2. 存在唯一的一个被称作最后一个的数据元素
  3. 除第一个之外,集合中的每个数据元素均只有一个前驱
  4. 除最后一个之外,集合中每个数据元素均只有一个后续
很简单对吧,想象之前排队的例子就知道啦。

好,下面就开始代码实现咯。线性表在具体实现中又分为顺序表示和链式表示,而链式表示中又分为线性链表,循环链表和双向链表。下面我将介绍各种方式的Java实现。

基本操作

不管是如何实现的,一个线性表的基本操作都是一样的,所以我们先创建一个定义了线性表基本操作的接口 ListBase
/**
 * 线性链表的所有操作接口
 * @author Like
 *
 */
public interface ListBase<T> {

	/**
	 * 清空列表
	 */
	void clearList();
	
	/**
	 * 判断列表是否为空
	 * @return 如果为空,返回true,否则返回false
	 */
	boolean isEmpty();
	
	/**
	 * 获得列表中元素额数量
	 * @return
	 */
	int size();
	
	/**
	 * 获得列表第index个元素
	 * @param index 列表中的位置
	 * @return
	 */
	T get(int index) throws Exception;
	
	/**
	 * 如果t是列表中的元素,且不是第一个,则返回t的前一个元素,否则返回null
	 * @param t
	 * @return
	 */
	T preElem(T t) throws Exception;
	
	/**
	 * 如果t是列表中的元素,且不是最后一个,则返回t的下一个元素,否者返回null 
	 * @param t
	 */
	T nextElem(T t) throws Exception;
	
	/**
	 * 将t插入到列表第index元素之前
	 * @param t
	 */
	void add(int index, T t) throws Exception;
	
	/**
	 * 删除列表的第index个元素
	 * @param index
	 */
	void remove(int index) throws Exception;
	
	/**
	 * 打印列表中的所有数据
	 */
	void printAll();
	
}


顺序实现

以下是通过数组实现的顺序列表。
public class LinearList<T> implements ListBase<T> {
	
	private T[] mts;
	// 数组创建时的默认长度
	private int mDefaultLength = 10;
	// 当数组空间不足时,扩充的数组长度
	private int mDefaultExpandLength = 5;
	// 记录当前插入数据个数
	private int mSize = 0;
	// 定义两个异常
	private Exception mSTZeroException = new Exception("数值必须大于0");
	private Exception mBTLengthException = new Exception("超出列表长度");
	private Exception mNotInListException = new Exception("元素不在列表中");
	private Exception mFirstException = new Exception("已经是第一个元素");
	private Exception mLastException = new Exception("已经是最后一个元素");
	
	@SuppressWarnings("unchecked")
	public LinearList() {
		mts = (T[]) new Object[mDefaultLength];
	}

	@SuppressWarnings("unchecked")
	@Override
	public void clearList() {
		mts = (T[]) new Object[mDefaultLength];
		mSize = 0;
	}

	@Override
	public boolean isEmpty() {
		return mSize == 0;
	}

	@Override
	public int size() {
		return mSize;
	}

	@Override
	public T get(int index) throws Exception {
		if(index > mSize - 1)
			throw mBTLengthException;
		if(index < 0)
			throw mSTZeroException;
		return mts[index];
	}

	@Override
	public T preElem(T t) throws Exception {
		int index = getElementIndex(t);
		if(index == -1)
			throw mNotInListException;
		if(index == 0) 
			throw mFirstException;
		return mts[index-1];
	}

	@Override
	public T nextElem(T t) throws Exception {
		int index = getElementIndex(t);
		if(index == -1)
			throw mNotInListException;
		if(index == mts.length) 
			throw mLastException;
		return mts[index+1];
	}

	@Override
	public void add(int index, T t) throws Exception {
		mSize++;
		// 对index范围进行判断
		if(index < 0) 
			throw mSTZeroException;
		if(index > mSize - 1)
			throw mBTLengthException;
		// 如果超出数组长度,对数组进行扩容
		if(mSize == mts.length) {
			arrayExpand(mDefaultExpandLength);
		}
		// 因为要将数据插入到index之前,所有从index开始所有数据都要往后移一位
		for(int i=mSize; i>index; i--) {
			mts[i] = mts[i-1];
		}
		mts[index] = t;
		
	}

	@Override
	public void remove(int index) throws Exception {
		mSize--;
		if(index < 0) 
			throw mSTZeroException;
		if(index > mSize - 1)
			throw mBTLengthException;
		// 将index之后的数据全部左移一位,实现删除
		for(int i=index; i<mSize; i++) {
			mts[i] = mts[i+1];
		}
	}

	@Override
	public void printAll() {
		for(int i=0; i<mSize; i++) {
			System.out.print(mts[i] + "    ");
		}
	}
	
	// 通过Arrays的copyOf来扩展数组的空间
	private void arrayExpand(int expandLength) {
		mts = Arrays.copyOf(mts, expandLength + mts.length);
	}
	
	// 通过给定元素找寻其在数组中的位置,如果不在数组中返回-1
	private int getElementIndex(T t) {
		for(int i=0; i<mSize; i++) {
			if(mts[i].equals(t)) {
				return i;
			}
		}
		return -1;
	}
	
	public static void main(String[] args) throws Exception {
		ListBase<String> list = new LinearList<>();
		for(int i=0; i<20; i++) {
			list.add(i, "" + i);
		}
		list.printAll();
	}

}


就此,顺序列表已经实现成功,使用起来就和ArrayList一样。
public static void main(String[] args) throws Exception {
	ListBase<String> list = new LinearList<>();
	for(int i=0; i<20; i++) {
		list.add(i, "" + i);
	}
	list.printAll();
}

总结

通过上面的实现可以明显的感觉到,顺序的线性表十分 善于进行查询的操作,只要知道位置可以快速定位到需要的找的元素。而 对于插入和删除操作,则十分繁琐,需要将插入或删除的元素之后所有元素进行移位操作。

下一章将通过链表的方式实现。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值