数据结构:Java实现线性表中的顺序表

1. 线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。
线性表是一种在实际中广泛使用的数据结构,常见 的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

前躯元素和后继元素

若A元素在B元素的前面,则将A称为B的前驱元素,B称为A的后继元素

主要特征

数据之间是“一对一”的逻辑关系
第一个元素没有前驱,称为头结点;最后一个元素没有后继,称为尾结点;除了第一个元素和最后一个元素外,其他数据元素有且仅有一个前驱和一个后继。

什么是顺序表?

静态顺序表:使用定长数组存储。
动态顺序表:使用动态开辟的数组存储

    线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表在逻辑结构上相邻的元素存储在连续的物理存储单元中,即:通过数据元素物理存储的连续性来反应元素之间逻辑上的相邻关系。采用顺序存储结构存储的线性表通常简称为顺序表。
       顺序存储的线性表的特点:
◆ 线性表的逻辑顺序与物理顺序一致;
◆ 数据元素之间的关系是以元素在计算机内“物理位置相邻”来体现。
一个标准的顺序表需要实现以下基本操作:

  1、初始化顺序表

  2、销毁顺序表

  3、清空顺序表

  4、检测顺序表是否为空

  5、返回顺序表的元素个数

  6、返回顺序表中指定位置元素的值

  7、返回顺序表中第一个与指定值相同的元素的位置

  8、返回指定元素的直接前驱

  9、返回指定元素的直接后继

  10、向指定位置插入元素

  11、删除指定位置的元素

  12、遍历顺序表

这里写图片描述

定义一个接口,相当于封装数据

如果不了解什么是数据封装的话等会我做一个什么是数据封装的博客(需等两天欧)

package LinearTable;

public interface ISequence {
    // 在 pos 位置插入 val
    boolean add(int pos, Object data);

    // 查找关键字 key 找到返回 key 的下表,没有返回 -1
    int search(Object key);

    // 查找是否包含关键字 key 是否在顺序表当中(这个和search有点冲突)
    boolean contains(Object key);

    // 得到 pos 位置的值
    Object getPos(int pos);

    // 删除第一次出现的关键字 key
    Object remove(Object key);

    // 得到顺序表的长度
    int size();

    // 打印顺序表
    void display();

    // 清空顺序表以防内存泄漏
    void clear();

    //判断是否为满
    boolean isFull();

    //判断是否为空
    boolean isEmpty();
}

实现接口里的每个方法

package LinearTable;

import java.util.Arrays;

public class SequenceImpl implements ISequence{
    //定义数组
    private Object[] elem;
    // 有效数据个数
    private int usedSize;
    //定义数组长度
    private static final int DEFAULT_SIZE = 10;

    //初始化数组
    //为什么都用this,因为this指向全局变量数组,不会出现数据混乱,你可以去理清一下什么是全局和局部变量
    public SequenceImpl() {
        this.elem = new Object[DEFAULT_SIZE];
        this.usedSize = 0;
    }

 /*   在 pos 位置插入 value(数值)
    @param pos:要插入的位置
    @param data:要插入的值
    插入成功返回true,否则返回false
 */

    @Override
    public boolean add(int pos, Object data) {
        //先判断是否满了再判断是否越界,这里面有一个逻辑问题,不能先判断是否越界
        // 1. 判断是否满了,如果满了进行扩容,每次扩容都是双倍增长
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem, 2*this.elem.length);
        }

        // 2. 判断pos位置的合法性,判断position位置是否越界
        if (pos < 0 || pos >this.elem.length-1) {
            return false;
        }

        // 3. 把pos位置以及之后的数全部向后挪一个位置
        for (int i = this.usedSize-1; i >= pos; i--) {
            this.elem[i+1] = this.elem[i];
        }

        // 4. 在 pos 位置插入 val
        this.elem[pos] = data;

        // 5. 更新长度
        this.usedSize++;

        return true;
    }

/*    查找关键字 key 找到返回 key 的下标,没有返回 -1
    @param key 关键字的值
    @return 查找成功返回true,失败返回false
*/
    @Override
    public int search(Object key) {
        // 1. 判断是否为空
        if (isEmpty()) {
            return -1;
        }

        // 2. 遍历查找
        for (int i = 0; i < this.elem.length; i++) {
            // 注意:判断条件不能写成:this.elem[i] == key
            if (this.elem[i].equals(key)) {
                return i;
            }
        }
        return -1;
    }

/*  查找是否包含相同关键字 key 是否在顺序表当中(这个和search有点冲突)
    @param key 关键字的值
    @return 查找成功返回true,失败返回false
*/
    @Override
    public boolean contains(Object key) {
        // 1. 判断是否为空
        if (isEmpty()) {
            return false;
        }

        // 2. 遍历查找
        for (int i = 0; i < this.elem.length; i++) {
            // 注意:判断条件不能写成:this.elem[i] == key
            if (this.elem[i].equals(key)) {
                return true;
            }
        }
        return false;
    }

/*   得到 pos 位置的值
     @param pos 得到的值的位置
     @return 成功得到 pos位置的值返回true,否则返回false
*/
    @Override
    public Object getPos(int pos) {
        // 1. 判断位置是否合法
        if (pos<0 || pos>=this.elem.length) {
            return null;
        }

        // 2. 位置合法
        return this.elem[pos];
    }

/*   删除第一次出现的关键字 key
     @param key 关键字
     @return
*/
    @Override
    public Object remove(Object key) {
        // 1. 先查表看有没有这个关键字
        // index:关键字下标
        int index = search(key);

        // 2. 若表里没有这个关键字
        if (index == -1) {
            return null;
        }

        // 3. 表里有这个关键字
        Object data = this.elem[index];
        int i;
        // 删除第一次出现的关键字 key,把key后面的数全部向前挪一个位置
        for (i = index; i < this.usedSize; i++) {
            elem[i] = elem[i+1];
        }
        this.usedSize--;
        this.elem[i+1] = null;
        return data;
    }

/*    得到顺序表的长度
    @return 顺序表的长度
*/
    @Override
    public int size() {
        return this.usedSize;
    }

//    打印顺序表
    @Override
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
        System.out.println();
    }

//  清空顺序表以防内存泄漏
    @Override
    public void clear() {
        for (int i = 0; i < this.usedSize; i++) {
            this.elem[i] = null;
        }
    }

 /*   判断是否为满
    return 满了返回true,否则返回false
 */
    @Override
    public boolean isFull() {
        return this.elem.length == this.usedSize;
    }

   /* 判断是否为空
    表为空返回true,否则返回false
    */
    @Override
    public boolean isEmpty() {
        return this.usedSize == 0;
    }

}

测试方法的正确性

package LinearTable;

public class SequenceTable {
    public static void main(String[] args) {
        SequenceImpl sequence=new SequenceImpl();

        //你可以插入你想插入的数据
        for (int i = 0; i < 10; i++) {
            sequence.add(i,i);
        }
        System.out.println("在长度为10的数组范围内插入数据:");
        sequence.display();

        //扩容
        for (int i = 10; i < 20; i++) {
            sequence.add(i,i);
        }
        System.out.println("扩容:");
        sequence.display();

        //插入数据
        System.out.println("随机位置插入数据:");
        sequence.add(9,"list");
        sequence.display();

        //查找数据
        System.out.println("search查找一个数据:"+sequence.search("list"));
        System.out.println("contains查找一个数据:"+sequence.contains("list"));

        //查找某一个位置对应的值
        System.out.println("查找某一个位置对应的值:"+sequence.getPos(9));

        //删除下标为key的一个数据
        System.out.println("删除下标为key的一个数据:"+sequence.remove(8));
        sequence.display();

        //顺序表的长度
        System.out.println("得到顺序表的长度:"+sequence.size());
    }
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值