集合----顺序存储的实现

一 、集合的定义

   集合是由任意类型互不相同的数据元素组成的,它们之间没有任何逻辑关系。每一个元素都是相对独立的。在Java中,Object类是所有对象的根类,可以代表集合中任意一种数据类型。在Java中,Set接口来表示集合。集合分为顺序存储结构和链式存储结构,顺序结构是由数组来实现的,本博客讲述顺序存储结构相关代码的实现。


二、集合的抽象数据类型

抽象数据类型(ADT)包括数据和操作两个部分,数据也为一个集合,采用任意方式存储,操作指的就是方法。抽象数据类型定义如下:
ADT Set is
  Data :
    采用顺序结构存储
  Operation:
    initSet();   //创建一个集合并初始化为空集
    add(obj);    //想集合中插入一个元素
    remove(obj);  //从集合中删除指定的元素
    contains(obj);  //判断一个给定元素是否包含集合
    value(i);     //返回集合中第i个元素的值
    find(obj);    //从集合中按值查找并返回
    size();    //求出元素中集合的个数
    isEmpty();  //判断集合是否为空
    output();   //输出集合中所有的元素
    union(set);   //求当前集合与参数集合set的并集并返回
    intersection(set); //求当前集合与参数集合set的交集并返回
    clear();    //清楚集合中的所有元素,使之变为空集
end Set


三 、操作的具体实现

1. 定义一个类SequenceSet,初始化集合为空

public class SequenceSet {
    private int maxSize = 10;       //定义数组的初始长度为10
    private Object[] setArray;      //定义存储集合的数组
    private int length;             //定义数组中所保存集合元素的个数

    public SequenceSet(){                   //无参构函数
        length = 0;                         //集合初始为空,长度为0
        setArray = new Object[maxSize];     //定义长度为maxSize的数组
    }

    public SequenceSet(int n){              //带初始长度的构造函数的定义
        if(n<=0){
            System.out.println("数组的长度要大于0,已退出运行!");
            System.exit(1);
        }
        length = 0;                         //集合初始为空,长度为0
        setArray = new Object[n];           //定义长度为n的数组
    }
}

2. 向集合中插入一个元素

  • 顺序查找集合中是否存在值为待插入值为obj的元素,若存在则不能插入,返回false,因为集合中不能存在相同的元素。
  • 检查数组长度是否够用,若不够用则创建一个新的数组,然后把原来的数组复制到新数组中,最后把新数组赋值给原来的数组。
  • 把obj的值插入到保存集合的后面的一个空位置上。
  • 集合的长度加1。
  • 插入成功返回true。
public boolean add(Object obj){
        //判断元素是否存在,若存在则返回false
        for (int i = 0; i < length; i++) {
            if(setArray[i].equals(obj)) return false;
        }
        //如果数组的长度已经分配完,需要在创建一个新的数组,并且把setArray的内容复制到新数组中,然后进行赋值。
        if(setArray.length == length){
            Object[] temp = new Object[length*2+1];
            System.arraycopy(setArray, 0, temp, 0, length);
            setArray = temp;
        }
        //增加元素,长度加1
        setArray[length] = obj;
        length++;
        return true;
    }

3.从集合中删除一个元素

  • 首先遍历数组,查找等于给定obj的元素
  • 若存在则删除,把空出的位置让最后一个元素填充,length减1,返回true。
  • 若不存在,则返回false,原集合的元素不变
public boolean remove(Object obj){
        for (int i = 0; i < length; i++) {      //遍历数组
            if(setArray[i] == obj){             //如果存在相等元素,则将最后一个元素赋给删除的元素,长度减1
                setArray[i] = setArray[length-1];   
                length--;
                return true;
            }
        }
        return false;
    }

4.判断一个元素是否属于该集合

public boolean contains(Object obj){
        //遍历数组,如存在相等的元素则返回true
        for (int i = 0; i < length; i++) {
            if(setArray[i].equals(obj)) return true;
        }
        return false;
    }

5.返回集合中第i个元素

public Object value(int i){
        if(i<=0||i>length){
            System.out.println("i应该在1和length之间!");
            System.exit(1);
        }
        return setArray[i-1];       //返回第i个位置,对应下标为i-1
    }

6.从集合中按值查找元素

public Object find(Object obj){
        //若集合中存在该元素,则返回obj,否则返回null
        for (int i = 0; i < length; i++) {
            if(setArray[i].equals(obj)) return obj;
        }
        return null;
    }

7.返回集合的长度

public int size(){
        return length;
    }

8.判断集合是否为空

public boolean isEmpty(){
        return length==0;   //只需判断长度是否为0即可
    }

9.输出集合中所有的元素

public void output(){
        for (int i = 0; i < length; i++) {
            System.out.println(setArray[i].toString());
        }
        System.out.println();
    }

10.求两个集合的并集

    public SequenceSet union(SequenceSet set){
        //遍历当前集合中所有的元素
        for (int i = 0; i < length; i++) {
            //向set集合中添加当前元素
            set.add(setArray[i]);
        }
        //返回并集集合,即set集合
        return set;

    }

11.求两个集合的交集

public SequenceSet intersection(SequenceSet set){
        //求两个集合的最小长度
        int minLength;
        if(length<set.length){ 
            minLength = length; 
        }else{ 
            minLength = set.length;
        }
        //创建一个SequenceSet对象,用作存放两个集合的交集
        SequenceSet tempSet = new SequenceSet(minLength);
        //遍历当前集合中的每一个元素
        for (int i = 0; i < length; i++) {
            Object x= setArray[i];
            //判断set集合是否包含该元素
            boolean b =set.contains(x);
            //如果包含当前集合中的该元素,则存入tempSet中,然后长度加1
            if(b){
                tempSet.setArray[tempSet.length++] = x;
            }
        }
        return tempSet;
    }

12.清空集合中的元素

public void clear(){
        length = 0;
    }

三、总结

  看完这篇文章大家对顺序结构应该有了清楚的认识了,顺序结构的底层实现是数组,然而数组的长度是不可变的,所有出现了扩容的情况,下次我们将讲述集合的另一种实现方式–链表。上面的代码大家应该手动敲一遍,你会有很大收获。学无止境,加油吧,少年!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值