数据结构-线性表(1)

线性表

线性表的定义

  • 线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列.

  • 线性表是一种抽象数据 类型;数组是一种具体的数据结构。线性表与数组的逻辑结构是不一样的,线性表是元素之 间具有1对1的线性关系的数据元素的集合,而数组是一组数据元素到数组下标的一一映射。 并且从物理性质来看,数组中相邻的元素是连续地存储在内存中的;线性表只是一个抽象的 数学结构,并不具有具体的物理形式,线性表需要通过其它有具体物理形式的数据结构来实 现。在线性表的具体实现中,表中相邻的元素不一定存储在连续的内存空间中,除非表是用 数组来实现的。对于数组,可以利用其下标在一个操作内随机存取任意位置上的元素;对于 线性表,只能根据当前元素找到其前驱或后继,因此要存取序号为i的元素,一般不能在一 个操作内实现,除非表是用数组实现的。

线性表的顺序存储与实现

1.1List接口
package cn.wjy.list;

public interface List {

    /**
     * 返回线性表的大小,及数据元素的个数
     *
     * @return
     */
    public int getSize();

    /**
     * 判断线性表是否为空
     *
     * @return
     */
    public boolean isEmpty();

    /**
     * 判断线性表是否包含数据元素e
     *
     * @param e
     * @return
     */
    public boolean contains(Object e);

    /**
     * 返回数据元素e在线性表中的序号
     *
     * @param e
     * @return
     */
    public int indexOf(Object e);

    /**
     * 将数据元素e插入到线性表中i号位置
     *
     * @param i
     * @param e
     * @throws OutOfBoundaryException
     */
    public void insert(int i, Object e) throws OutOfBoundaryException;

    /**
     * 将数据元素e插入到元素obj之前
     *
     * @param obj
     * @param e
     * @return
     */
    public boolean insertBefore(Object obj, Object e);

    /**
     * 将数据元素e插入到元素obj之后
     *
     * @param obj
     * @param e
     * @return
     */
    public boolean insertAfter(Object obj, Object e);

    /**
     * 删除线性表中序号为i的元素,并返回之
     *
     * @param i
     * @return
     * @throws OutOfBoundaryException
     */
    public Object remove(int i) throws OutOfBoundaryException;

    /**
     * 删除线性表中第一个与e相同的元素
     *
     * @param e
     * @return
     */
    public boolean remove(Object e);

    /**
     * 替换线性表中序号为i的数据元素为e,返回原数据元素
     *
     * @param i
     * @param e
     * @return
     * @throws OutOfBoundaryException
     */
    public Object replace(int i, Object e) throws OutOfBoundaryException;

    /**
     * 返回线性表中序号为i的数据元素
     *
     * @param i
     * @return
     * @throws OutOfBoundaryException
     */
    public Object get(int i) throws OutOfBoundaryException;
}
1.2出现序号越界时抛出异常
public class OutOfBoundaryException extends RuntimeException {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public OutOfBoundaryException(String err) {
        super(err);
    }

}
1.3 Strategy 接口
  • 所有数据元素的类型都使用 Object 来替代,这样做是 为了程序的通用性,即一种抽象数据类型的实现可以用于所有数据元素。但是这样做带来了 另一个需要解决的问题,即完成数据元素之间比较大小或是否相等的问题。在使用 Object 类型的变量指代了所有数据类型之后,那么所有种类的数据元素的比较就都需要使用 Object 类型的变量来完成,但是不同数据元素的比较方法或策略是不一样的。例如字符串的比较是 使用 java.lang.String 类的 compareTo 和 equals 方法;而基本的数值型数据是使用关系运算符 来完成的;其他各种不同的类的比较方法就更加千差万别多种多样了,即使同一个类的比较 方法在不同的情况下也会不同,例如两个学生之间的比较有时可以用学号的字典顺序来进 行,有时可能又需要使用成绩来比较。因此我们无法简单的在两个 Object 类型的变量之间 使用"= ="、"<"等关系运算符来完成各种不同数据元素之间的比较操作,同时 Java 也不提供 运算符的重载.

  • 使用 Strategy 接口可以实现各种不同数据元素相互之间独立的比较策略。在实现各种抽 象数据类型时,例如线性表,可以使用 Strategy 接口变量来完成形式上的比较,然后在创建 每个抽象数据类型的实例时,例如一个具体的用于学生的线性表时,可以引入一个实际实现了 Strategy 接口的策略类对象,例如实现了 Strategy 接口的学生比较策略类对象。使用这一策略的另一优点在于,一旦不想继续使用原先的比较策略对象,随时可以使用另一个比较 策略对象将其替换,而不用修改抽象数据类型的具体实现。

package cn.wjy.list;
public interface Strategy {
    /**
     * 判断两个数据元素是否相等
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public boolean equal(Object obj1, Object obj2);

    /**
     * 判断两个数据元素的大小 obj1>obj2 return -1; obj1=obj2 return 0; obj1<obj2 reurn 1
     *
     * @param obj1
     * @param obj2
     * @return
     */
    public int compare(Object obj1, Object obj2);

}


package cn.wjy.list;

public class DefaultStrategy implements Strategy {

    @Override
    public boolean equal(Object obj1, Object obj2) {
        return obj1.toString().equals(obj2.toString());
    }

    @Override
    public int compare(Object obj1, Object obj2) {
        int temp = obj1.toString().compareTo(obj2.toString());
        if (temp == 0) {
            return 0;
        } else if (temp > 0) {
            return 1;
        } else {
            return -1;
        }

    }

}


package cn.wjy.list;

public class StudentStrategy implements Strategy {

    @Override
    public boolean equal(Object obj1, Object obj2) {
        if (obj1 instanceof Student && obj2 instanceof Student) {
            Student s1 = (Student) obj1;
            Student s2 = (Student) obj2;
            return s1.getSId().equals(s2.getSId());
        } else {
            return false;
        }
    }

    @Override
    public int compare(Object obj1, Object obj2) {
        if (obj1 instanceof Student && obj2 instanceof Student) {
            Student s1 = (Student) obj1;
            Student s2 = (Student) obj2;
            return s1.getSId().compareTo(s2.getSId());
        } else {
            return obj1.toString().compareTo(obj2.toString());
        }
    }

}
2.线性表的数组实现
public class ListArray implements List {

    private final int LEN = 9;// 数组的默认大小
    private Strategy strategy; // 数据元素比较策略
    private int size;// 线性表中数据元素的个数
    private Object[] elements; // 数据元素数组

    public ListArray() {
        this(new DefaultStrategy());
    }

    public ListArray(Strategy strategy) {
        this.strategy = strategy;
        size = 0;
        elements = new Object[LEN];
    }

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

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

    @Override
    public boolean contains(Object e) {
            return indexOf(e) != -1;
    }

    @Override
    public int indexOf(Object e) {
        for (int i = 0; i < size; i++)
            if (strategy.equal(e, elements[i]))
                return i;
        return -1;
    }

    /**
     * 扩充数组
     */
    private void expandSpace() {
        Object[] a = new Object[elements.length * 2];
        for (int i = 0; i < elements.length; i++)
            a[i] = elements[i];
        elements = a;
    }

    @Override
    public void insert(int i, Object e) throws OutOfBoundaryException {
        if (i < 0 || i > size)
            throw new OutOfBoundaryException("错误,指定的插入序号越界");
        if (size >= elements.length)
            expandSpace();
        for (int j = size; j > i; j--)
            elements[j] = elements[j - 1];
        elements[i] = e;
        size++;
        return;
    }

    @Override
    public boolean insertBefore(Object obj, Object e) {
        int i = indexOf(obj);
        if (i < 0)
            return false;
        insert(i, e);
        return true;
    }

    @Override
    public boolean insertAfter(Object obj, Object e) {
        int i = indexOf(obj);
        if (i < 0)
            return false;
        insert(i + 1, e);
        return true;
    }

    @Override
    public Object remove(int i) throws OutOfBoundaryException {
        if (i < 0 || i >= size)
            throw new OutOfBoundaryException("错误,指定的插入序号越界");
        Object obj = elements[i];
        for (int j = i; j < size - 1; j++)
            elements[j] = elements[j + 1];
        elements[--size] = null;
        return obj;
    }

    @Override
    public boolean remove(Object e) throws OutOfBoundaryException {
        int i = indexOf(e);
        if (i < 0)
            return false;
        remove(i);
        return true;
    }

    @Override
    public Object replace(int i, Object e) throws OutOfBoundaryException {
        if (i < 0 || i >= size)
            throw new OutOfBoundaryException("错误,指定的序号越界");
        Object obj = elements[i];
        elements[i] = e;
        return obj;
    }

    @Override
    public Object get(int i) throws OutOfBoundaryException {
        if (i < 0 || i >= size)
            throw new OutOfBoundaryException("错误,指定的序号越界");
        return elements[i];
    }

}

转载于:https://www.cnblogs.com/Onlywjy/p/6260304.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值