一、集合的定义
集合的定义:集合是集合结构的简称,它是有同一类型的互不相同的数据元素聚集而成,元素之间不存在任何逻辑依赖关系。例如:{ a1,a2,a3,a4,a5,......an}
集合长度:数据元素的个数。
二、集合存储结构和实现
2.1顺序存储结构和操作实现
在一块存储空间内连续存储集合中的每个元素
定义集合接口—》实现接口类—》实现接口中的方法。
定义集合接口
public interface Set {
boolean add(Object obj); //向集合中插入一个元素
boolean remove(Object obj); //从集合中删除一个元素
boolean contains(Object obj); //判断元素obj是否属于集合
Object value(int i); //返回集合中第i个元素的值
Object find(Object obj); //查找元素并返回
int size(); //返回集合中元素的个数
boolean isEmpty(); //判断集合是否为空
void output(); //输出集合中的元素
Set union(Set set); //返回当前集合和参数集合set的并集
Set intersection(Set set); //返回当前集合和参数集合set的交集
void clear(); //清除集合中的所有元素,返回空集
}
实现接口Set的顺序集合类的定义
和接口中各个方法的具体操作实现
public class SequenceSet implements Set{
final int minSize=10; //数组初始长度
private Object [] setArray; //数组声明,采用数组存储的一个集合
private int len; //保存集合的当前长度
//无参构造方法定义
public SequenceSet()
{
len=0;
//数组初始长度
setArray=new Object[minSize];
}
//带有指定数组长度参数的构造方法定义
public SequenceSet(int n)
{
if(n<minSize)
n=minSize;
len=0;
setArray=new Object[n];
}
//向集合中插入一个元素
public boolean add(Object obj) {
for(int i=0;i<len;i++)
{
if(setArray[i].equals(obj))
{
return false;
}
}
if(len==setArray.length)
{
Object[] p=new Object[len*2];
for(int i=0;i<len;i++)
{
p[i]=setArray[i];
setArray=p;
}
}
setArray[len]=obj;
len++;
return true;
}
//从集合中删除一个元素
public boolean remove(Object obj) {
int i;
for(i=0;i<len;i++)
{
if(setArray[i].equals(obj))
break;
}
if(i<len)
{
//把集合中最后一个元素赋给被删除元素位置
setArray[i]=setArray[len-1];
len--;
return true;
}
else
return false;
}
//判断元素obj是否属于集合
public boolean contains(Object obj) {
for(int i=0;i<len;i++)
{
if(setArray[i].equals(obj))
{
return true;
}
}
return false;
}
//返回集合中第i个元素的值
public Object value(int i) {
if(i<=0||i>len)
{
System.out.println("参数i有误!应在1到"+len+"之间");
System.exit(1);
}
return setArray[i-1];
}
//查找元素并返回
public Object find(Object obj) {
for(int i=0;i<len;i++)
{
if(setArray[i].equals(obj))
{
return obj;
}
}
return null;
}
//返回集合中元素的个数
public int size() {
return len;
}
//判断集合是否为空
public boolean isEmpty() {
if(len==0)
{
return true;
}
return false;
}
//输出集合中的元素
public void output() {
for(int i=0;i<len;i++)
{
System.out.println(setArray[i].toString());
}
System.out.println();
}
//返回当前集合和参数集合set的并集
public Set union(Set set) {
//把参数转换为顺序集合类
SequenceSet dset=(SequenceSet)set;
//定义新集合
SequenceSet setTemp=new SequenceSet(len+dset.len);
int i;
for(i=0;i<len;i++)
{
setTemp.setArray[i]=setArray[i];
}
setTemp.len=len;
//向新集合中依次插入dset中的元素
for(i=0;i<dset.len;i++)
{
Object x=dset.setArray[i];
//从当前集合中找元素x,是否存在
boolean b=contains(x);
if(!b)
{
setTemp.setArray[setTemp.len]=x;
}
}
//返回新集合
return setTemp;
}
//返回当前集合和参数集合set的交集
public Set intersection(Set set) {
SequenceSet dset=(SequenceSet)set;
int newLen;
if(len<dset.len)
{
newLen=len;
}
else
{
newLen=dset.len;
}
//定义新的集合
SequenceSet setTemp=new SequenceSet(newLen);
for(int i=0;i<dset.len;i++)
{
Object x=dset.setArray[i];
boolean b=contains(x);
if(b)
{
setTemp.setArray[setTemp.len++]=x;
}
}
return setTemp;
}
//清除集合中的所有元素,返回空集
public void clear()
{
len=0;
}
}
2.2 链接存储结构和操作实现
结点类的定义
public class Node {
Object element; //数值域
Node next; //指针域
public Node(Node nt) //只对next赋值
{
next=nt;
}
public Node(Object obj,Node nt) //对两个域同时赋值
{
element=obj;
next=nt;
}
}
链接集合类的定义和实现
public class LinkSet implements Set {
private Node head; //表头指针
private int len; //链表长度(集合长度)
//构造方法
public LinkSet() {
len=0; //集合初始长度为0
head=new Node(null); //初始建立由head指向的附加头结点,next域为空
//表示初始为一个空链表
}
//向集合中插入一个元素
public boolean add(Object obj) {
//把元素obj插入到链表尾
Node p=head; //表头指针赋给临时引用对象
while(p.next!=null)
{
if(p.next.element.equals(obj))
{
return false; //元素已存在,无法插入
}
else
{
p=p.next; //修改p,使他指向后继结点
}
}
p.next=new Node(obj,null); //在集合末尾插入新元素
len++; //集合长度加1
return true;
}
//从集合中删除一个元素
public boolean remove(Object obj) {
//从集合中删除一个元素为obj的结点
Node p=head; //表头指针赋值给临时对象
while(p.next!=null) //循环遍历单链表
{
if(p.next.element.equals(obj))
{ //找到被删除元素,退出遍历单链表
break;
}
else
{
p=p.next; //没找到,则指向后继结点
}
}
if(p.next!=null)
{
p.next=p.next.next; //从单链表中删除结点
len--; //链表长度减1
return true;
}
else
{
return false;
}
}
//判断元素obj是否属于集合
public boolean contains(Object obj) {
Node p=head;
while(p.next!=null)
{
if(p.next.element.equals(obj))
{
return true;
}
else
{
p=p.next;
}
}
return false;
}
//返回集合中第i个元素的值
public Object value(int i) {
if(i<0||i>len)
{
System.out.println("参数i值有误!应在1和"+len+"之间");
System.exit(1);
}
Node p=head;
int c=1;
while(p.next!=null)
{
if(c==i)
{
break;
}
else
{
c++;
p=p.next;
}
}
Object obj=p.element;
return obj;
}
//查找元素并返回
public Object find(Object obj) {
Node p=head;
while(p.next!=null)
{
if(p.next.element.equals(obj))
{
return p.next.element;
}
else
{
p=p.next;
}
}
return null;
}
//返回集合中元素的个数
public int size() {
return len;
}
//判断集合是否为空
public boolean isEmpty() {
return len==0;
}
//输出集合中的元素
public void output() {
Node p=head;
while(p.next!=null)
{
System.out.println(p.next.element.toString());
p=p.next;
}
}
//返回当前集合和参数集合set的并集
public Set union(Set set) {
LinkSet setTemp=new LinkSet(); //初始化保存并集的新链接集合为空
Node p=head.next; //p初始指向当前链表的表头结点
Node q=setTemp.head; //q初始指向并集新链表的附加表头结点
while(p!=null)
{
Node r=new Node(p.element,null); //根据p结点的值建立r新结点
q.next=r; //把r结点链接到新链表的表尾
q=r; //使q指向新链表的表尾结点
p=p.next; //使p指向下一个待处理的结点
}
setTemp.len=len; //置新链表集合的长度
LinkSet dset=(LinkSet)set; //把参数集合转换为链表集合
p=dset.head.next; //让p指向参数链表的表头结点
while(p!=null) //向新链表中依次插入参数链表中的每个结点值
{
Object x=p.element; //将结点的值赋给x
boolean b=contains(x); //从当前集合中查找值为x的结点
if(!b) //条件成立,表明x不在集合中,插入集合
{
q.next=new Node(x,null); //建立值为x的结点,插入到并集链表的末尾
q=q.next; //使q指向新的表尾结点
setTemp.len++; //新链表长度加1
}
p=p.next;
}
return setTemp;
}
//返回当前集合和参数集合set的交集
public Set intersection(Set set) {
LinkSet setTemp=new LinkSet(); //初始化保存交集的新连接集合为空
LinkSet dset=(LinkSet)set; //把参数集合转换为链接集合
Node p=dset.head.next; //p初始指向参数链表中的表头结点
Node q=setTemp.head; //q初始指向交集新链接集合的附加头结点
while(p!=null) //遍历参数链表中的每个结点
{
Object x=p.element; //将结点的值赋给x
boolean b=contains(x); //从当前集合中查找值为x的结点
if(b) //条件成立,表明x为交集中的元素
{
q.next=new Node(x,null); //建立值为x的结点,插入到交集链表的末尾
q=q.next; //使q指向新的表尾结点
setTemp.len++;
}
p=p.next; //使p指向参数链表中的下一个结点
}
return setTemp;
}
//清除集合中的所有元素,返回空集
public void clear()
{
len=0;
head.next=null;
}
}