数据结构——顺序表

在说顺序表之前,先认识一下线性表(Linear List)。线性表称为有序表(Ordered List),是数学概念应用在计算机科学中一种基本的数据结构。

  1. 线性表数据元素可以是任何一种类型,不过对于同一线性表的每一个元素都必须属于同一类型。
  2. 从数据在物理内存存储形式上线性表可以分为: 顺序表和链式表,本文主要做了顺序表相关操作的整理。

顺序表:

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
顺序表又可分为:
3. 静态顺序表:使用定长数组存储。
4. 动态顺序表:使用动态开辟的数组存储。
本文实现的是动态顺序表:

首先,在一个接口中声明顺序表的各项操作:

1.在pos位置插入data;
2. 查找关键字key 找到返回key的下标,没有返回null;
3. 查找是否包含关键字key是否在顺序表当中;
4. 得到pos位置的值;
5. 删除第一次出现的关键字key;
6. 得到顺序表的长度;
7. 打印顺序表;
8. 清空顺序表以防内存泄漏;

package com.Impl;

public interface ISequence {
    //在pos位置插入data
    boolean add(int pos,Object data);
    //查找关键字key 找到返回key的下标,没有返回null;
    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();
}

在具体实现类中实现接口中方法的实现:
package com.dao;

import com.Impl.ISequence;

import java.util.Arrays;

public class SequenceImpl implements ISequence {
    private Object[] elemDate;
    private int usedSize;
    public static final int DEFAULT_CAPACITY = 10;

    public SequenceImpl(){
        this.elemDate = new Object[DEFAULT_CAPACITY];
        this.usedSize = 0;
    }
    //判断顺序表是否为空
    private boolean isFull(){
        return this.usedSize == this.elemDate.length;
    }
    private boolean isEmpty(){
        return this.usedSize == 0;
    }
    @Override
    在pos位置插入data
    public boolean add(int pos, Object data) {
        //判断pos位置的合法性
        if(pos>this.usedSize || pos<0){
            return false;
        }
        if(isFull()){
            //扩容
            this.elemDate = Arrays.copyOf(this.elemDate,this.elemDate.length*2);
        }
        else{
            //移动数据
            for(int i = this.usedSize-1;i>=pos;i--){
                //Object[i] = Object[i-1];
                this.elemDate[i+1] = this.elemDate[i];
            }
        }

        //放入数据,并且usedSize++
        this.elemDate[pos] = data;
        this.usedSize++;

        return true;
    }


    //查找关键字key 找到返回key的下标,没有返回null;
    @Override
    public int search(Object key) {
        if(key == null){
            throw new UnsupportedOperationException("不可以传入null作为参数!");
        }
        if(isEmpty()){
            return -1;
        }
        for (int i = 0; i < this.usedSize; i++) {
            if(this.elemDate[i].equals(key)){
                return i;
            }

        }
        return -1;
    }
    //查找是否包含关键字key是否在顺序表当中(这个和search有点冲突)
    @Override
    public boolean contains(Object key) {
        if(key.equals(null)){
            throw new UnsupportedOperationException("不可以传入null作为参数!");
        }
        if(isEmpty()){
            return false;
        }
        for (int i = 0; i < this.usedSize; i++) {
            if(this.elemDate[i] == key){
                return true;
            }
        }
        return false;
    }
    //得到pos位置的值
    @Override
    public Object getPos(int pos) {
        if(pos<0 || pos >= this.usedSize){
            return null;
        }
        return this.elemDate[pos];
    }
    //删除第一次出现的关键字key
    @Override
    public Object remove(Object key) {
        int index = search(key);
        if(index == -1){
            return -1;
        }
        Object oldData = this.elemDate[index];
        int i = index;
        for(;i<this.usedSize-1;i++){
            this.elemDate[i] = this.elemDate[i+1];
        }
        this.elemDate[i+1] = null;
        this.usedSize--;
        return oldData;
    }
    //得到顺序表的长度
    @Override
    public int size() {
        return this.usedSize;
    }
    //打印顺序表
    @Override
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(this.elemDate[i]+" ");

        }
        System.out.println();

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

    }
}

在主方法中进行顺序表相关操作的测试:
package com.main;

import com.dao.SequenceImpl;

public class TestMain {
    public static void main(String[] args) {
        SequenceImpl sequence = new SequenceImpl();
        //插入
        for (int i = 10; i >=0; i--) {
            sequence.add(10-i,i);
        }
        //打印
        sequence.display();
        //输出顺序表大小
        System.out.println(sequence.size());
        //判断元素"5"是否在顺序表中
        System.out.println(sequence.contains(5));
        //得到3位置的值
        System.out.println(sequence.getPos(3));
        //返回数字9(存在)和数字15(不存在)对应的下标
        System.out.println(sequence.search(9));
        System.out.println(sequence.search(15));
        //删除首个出现的"6",并打印一次观察
        sequence.remove(6);
        sequence.display();
        //将顺序表清空,并打印一次
        System.out.println("将顺序表清空,并打印一次:");
        sequence.clear();
        sequence.display();


    }
}

顺序表分析:
优点:

便于随机访问查找

缺点:

不便于插⼊,删除(末尾插⼊或删除⽐较⽅便,但中间/头部的插入删除,时间复杂度为O(N))

场景:

需要⼤量访问元素,尾删,尾插较多时使⽤顺序表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值