数据结构——线性表的实现

线性表是同一数据类型的一个有限集合,数据之间在逻辑上存在线性关系。线性表中的元素的个数称为线性表的长度。

线性表的抽象数据类型由带结构的数据和操作组成。线性表接口List的定义如下:

<pre name="code" class="java">package list;

/**
 * 线性表接口List的定义如下
 *
 */
public interface List<E> {
	public Object value(int pos);// 返回线性表中地pos个元素的值

	boolean add(Object obj, int pos);// 向第pos个元素位置插入一个元素obj

	void remove(int pos);// 删除第pos个元素并返回,若不存在返回空

	int find(Object obj);// 从表头查找等于obj值的第一个元素,返回序号

	boolean modify(Object obj, int pos);// 用obj修改线性表中给定序号pos的元素值

	boolean isEmpty();// 判断线性表是否为空

	int size();// 返回线性表的长度

	String forward();// 正向遍历输出线性表中所有元素

	String backward();// 反向遍历输出线性表中所有元素

	void clear();// 清除线性表中所有元素
	
	boolean add(Object obj);// 向线性表尾部插入元素
}
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">线性表运算举例</span>


假定学生类Student的定义如下:

package list;

public class Student implements Comparable<Object> {

	private String numb;// 学号
	private String name;// 姓名
	private int grade;// 成绩

	public Student(String numb, String name, int grade) {
		this.numb = numb;
		this.name = name;
		this.grade = grade;
	}

	@Override
	public String toString() {
		return this.numb + "-->" + this.name + "-->" + this.grade;
	}

	public int compareTo(Object o) {
		Student s = (Student) o;
		return this.grade - s.getGrade();
	}

	public String getNumb() {
		return numb;
	}

	public void setNumb(String numb) {
		this.numb = numb;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getGrade() {
		return grade;
	}

	public void setGrade(int grade) {
		this.grade = grade;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + grade;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((numb == null) ? 0 : numb.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (grade != other.grade)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (numb == null) {
			if (other.numb != null)
				return false;
		} else if (!numb.equals(other.numb))
			return false;
		return true;
	}
}

定义一个线性表,并实现其中方法:

package list;

public class SequenceList<E> implements List<E> {

	public static final int minSize = 10;// 数组初始长度
	private Object[] listArray;// 声明数组,元素类型为Object
	private int length;// 线性表的长度

	public SequenceList() {// 无参构造
		this.length = 0;// 线性表初始长度
		listArray = new Object[minSize];// 初始化一个长度为10的空数组
	}

	public SequenceList(int n) {// 带初始长度的构造器
		if (n < minSize)// 条件成立,将n修改为minSize
			n = minSize;
		this.length = 0;// 线性表初始长度
		listArray = new Object[n];// 初始化一个长度为10的空数组
	}

	public Object value(int index) {// 返回线性表中第index个元素的值,index = 0表示在数组第一个位置放进元素
		if (index >= 0 && index <= this.length - 1) {
			return this.listArray[index];
		}
		return null;
	}

	/**
	 * 向线性表中指定位置插入一个元素 假定插入到第pos个元素的位置
	 * 
	 * 1.检查插入位置是否有效
	 * 
	 * 2.检查线性表的存储空间是否已占满
	 * 
	 * 3.空出下标为pos的位置
	 * 
	 * 4.把obj放到pos的位置
	 * 
	 * 5.返回真,插入成功
	 * 
	 * 平均时间复杂度为O(n)
	 * 
	 * @param obj
	 * @param pos
	 * @return2
	 */
	public boolean add(Object obj, int pos) {
		if (pos < 0 || pos > this.length) {// 检查插入的位置是否合法
			return false;
		}

		if (this.length == listArray.length) {// 数组空间用完的情况下,进行再分配
			Object[] p = new Object[this.length * 2];// 新数组的空间为原数组的2倍
			for (int i = 0; i < this.length; i++) {
				p[i] = listArray[i];// 复制原线性表
				listArray = p;
			}
		}

		for (int i = this.length - 1; i >= pos; i--) {// 为待插入元素空出位置,从第pos开始向后移动
			listArray[i + 1] = listArray[i];
		}

		listArray[pos] = obj;
		this.length++;
		return true;
	}

	/**
	 * 从线性表中删除给定位置的元素
	 * 
	 * 线性表中元素的位置:[0,length -1]
	 * 
	 * 平均时间复杂度为O(n)
	 */
	public void remove(int pos) {
		if (pos >= 0 && pos <= this.length - 1) {
			int numMoved = this.length - 1 - pos;
			if (numMoved > 0) {// 如果删除的位置不是线性表的最后一个元素的位置,需要移动线性表中元素
				for (int i = 0; i < this.length; i++) {
					listArray[i] = listArray[i + 1];
				}
			}
			listArray[--this.length] = null;// 如果删除的位置是线性表的最后一个元素的位置,释放最后一个位置的
		}
	}

	/**
	 * 从线性表中按顺序查找值为obj的元素,返回第一个匹配元素的位置
	 */
	public int find(Object obj) {
		for (int i = 0; i < this.length; i++) {
			if (listArray[i].equals(obj)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 修改线性表中给定位置的元素值
	 */
	public boolean modify(Object obj, int pos) {
		if (pos < 0 || pos > this.length - 1) {
			return false;
		}

		listArray[pos] = obj;
		return true;
	}

	/**
	 * 判断线性表是否为空
	 */
	public boolean isEmpty() {
		return this.length == 0;
	}

	/**
	 * 求线性表的长度
	 */
	public int size() {
		return this.length;
	}

	/**
	 * 正向遍历线性表中所有元素
	 * 
	 * @return
	 */
	public String forward() {
		String str = "";
		for (int i = 0; i < this.length; i++) {
			str += listArray[i].toString() + "\t";
		}
		return str;
	}

	/**
	 * 反向遍历线性表
	 */
	public String backward() {
		String str = "";
		for (int i = this.length - 1; i >= 0; i--) {
			str += listArray[i].toString() + "\t";
		}
		return str;
	}

	/**
	 * 清除线性表中的元素
	 */
	public void clear() {
		listArray = null;
		this.length = 0;
	}

	/**
	 * 重载方法向线性表尾部插入元素
	 * 
	 * 1.检查插入位置是否有效
	 * 
	 * 2.检查线性表的存储空间是否已占满
	 * 
	 * 3.把obj放到线性表尾部
	 * 
	 * 4.返回真,插入成功
	 * 
	 * 平均时间复杂度为O(n)
	 * 
	 */
	public boolean add(Object obj) {
		if (this.length == listArray.length) {// 数组空间用完的情况下,进行再分配
			Object[] p = new Object[this.length * 2];// 新数组的空间为原数组的2倍
			for (int i = 0; i < this.length; i++) {
				p[i] = listArray[i];// 复制原线性表
				listArray = p;
			}
		}

		listArray[this.length] = obj;
		this.length++;
		return true;
	}
}

测试所写的线性表:

package list;


public class TestList {
	public static void main(String[] args) {
		SequenceList<Student> list = new SequenceList<Student>();
		Student stu1 = new Student("001", "张三", 80);
		Student stu2 = new Student("002", "李四", 90);
		Student stu3 = new Student("003", "王五", 100);
		System.out.print("向线性表插入元素:	");
		list.add(stu1);
		list.add(stu2, 1);
		list.add(stu3);
		System.out.println(list.forward() + "\n" + "---------------------");
		System.out.println("从线性表删除的元素:	");
		list.remove(2);
		System.out.println(list.forward());
		System.out.println("从线性表查找指定元素的位置:	");
		System.out.println(list.find(stu1) + "\n" + "---------------------");
		System.out.println("修改线性表:	");
		Student stu4 = new Student("004", "赵六", 60);
		list.modify(stu4, 0);
		System.out.println(list.forward() + "\n" + "---------------------");
		System.out.println("判断线性表是否为空:	");
		System.out.println(list.isEmpty() + "\n" + "---------------------");
		System.out.println("判断线性表长度:	");
		System.out.println(list.size() + "\n" + "---------------------");
		System.out.println("反向遍历线性表:	");
		System.out.println(list.backward() + "\n" + "---------------------");
		System.out.println("清空线性表:	");
		list.clear();
		System.out.println(list.forward() + "\n" + "---------------------");
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值