set的链式存储linkedset

链式存储:逻辑上相邻,物理上不一定相邻,什么意思呢,比如在一堆数据中,A在B的前边,这叫逻辑相邻,而他们在计算机中的存储位置却不一定是相邻的,如果采用顺序存储,比如用一个数组来存储数据,那么逻辑相邻,物理也一定相邻,因为数组开辟的是连续的空间。因此说在采用链式存储的时候,当前的数据不仅存储数据元素,还要存储下一个元素的指针,我们把这样的数据用节点(node)来表示。如下图:




因为每一个节点都是这样的一个实例,所以我们需要创建一个NODE类,如下代码,类名为linearNode

package linkedset;

public class LinearNode<T> {
	//指向下一个节点的指针
	private LinearNode<T> next;
	//当前节点的元素
	private T element;
	public LinearNode(){
		next = null;
		element = null;
	}
	//含参数的构造函数
	
	public LinearNode(T element) {
		super();
		this.element = element;
	}
	public LinearNode<T> getNext(){
		return next;
	}
	public T getElement() {
		return element;
	}
	public void setElement(T element) {
		this.element = element;
	}
	public void setNext(LinearNode<T> next) {
		this.next = next;
	}
 	
}
这个类的实现是非常简单的。接下来就是实现set这个接口,set这个接口也是自己写的,因为原生的接口有很多方法我们用不上

package linkedset;

import java.util.Iterator;

public interface SetADT<T> {

	/**
	 * 要实现的方法
	 */
	
	//添加元素
	public void add(T element);
	
	//delete element
	public T remove(T element);
	
	//add all elements
	public void addAll(SetADT set);
	
	//compare two SetADT
	public boolean equals(SetADT<T> set);
	
	//是否包含某元素
	public boolean contains(T element);
	
	//求两个SET的交集
	public SetADT<T> union (SetADT<T> set);
	
	//判断是否为空
	public boolean isEmpty();
	
	//返回set的长度
	public int size();
	
	//将SET以转为字符串
	public String toString();
	
	//返回一个迭代器
	public Iterator<T> iterator();
	
}
现在我们写一个类来实现这个接口就可以了

package linkedset;

import java.util.Iterator;
import java.util.NoSuchElementException;
	/**
	 * @author jackee
	 * 
	 * @param <T>
	 */
public class LinkedSet<T> implements SetADT<T>{
	
	private int count;
	private LinearNode<T> contents;
	//构造函数
	public LinkedSet() {
		contents = null;
		count = 0;
	}

	@Override
	public void add(T element) {
		// TODO Auto-generated method stub
		if(!(contains(element))){
			LinearNode<T> node = new LinearNode<T>(element);
			node.setNext(contents);
			contents = node ;
			count++;
		}
	}

	@Override
	public T remove(T element) {
		LinearNode<T> previous,current;
		T result;
		boolean found = false;
		// TODO Auto-generated method stub
		//先判断首节点是不是要删除的元素
		if(contents.getElement().equals(element)){
			result = contents.getElement();
			contents = contents.getNext();
		}
		//遍历整个set,找到元素为element的节点
		else{
			
			previous = contents;
			current  = contents.getNext();
			for(int i = 1;i < count && !found;i++)
			{
				if(current.getElement().equals(element)){
					found = true;
				
				}else{
				previous = current;
				current = current.getNext();
				}
			}
			
		//没找到,抛出异常
			if(!found){
				throw new NoSuchElementException();
			}
			result = current.getElement();
			//将current的上一个元素的指针指向current的下一个元素
			previous.setNext(current.getNext());	
		}
		count--;
		
		return result;
	}

	@Override
	public void addAll(SetADT set) {
		// TODO Auto-generated method stub
		LinkedSet<T> set2 = (LinkedSet<T>) set;
		LinkedIterator<T> li = new LinkedIterator<T>(set2.contents, set2.count);
		while(li.hasNext()){
			add(li.next());
		}
	}

	@Override
	public boolean equals(SetADT<T> set) {
		// TODO Auto-generated method stub
		boolean result = false;
		LinkedSet<T> set2 = (LinkedSet<T>) set;
		LinkedIterator<T> li = new LinkedIterator<T>(set2.contents, set2.count);
		if(set2.size()!=this.size())
		{
			result = false;
		}
		else{
		while(li.hasNext()){
			if(!contains(li.next())){
				break;
			}else
			{
				result =true;
			}
		}
	}
		return result;
	}
	
	//输出set的值
	public void display()
	{
		LinkedIterator<T> li = new LinkedIterator<T>(contents, count);
		while(li.hasNext()){
			System.out.print(li.next()+"   ");
		}
	}
	
	
	//是否包含某元素
	@Override
	public boolean contains(T element) {
		// TODO Auto-generated method stub
		boolean found = false;
		LinkedIterator<T> li = new LinkedIterator<T>(contents, count);
		while(li.hasNext())
		{
			if(li.next().equals(element)){
				found = true ;
			}
		}
		return found;
	}

	
	//求交集
	@Override
	public SetADT<T> union(SetADT<T> set) {
		// TODO Auto-generated method stub
		return null;
	}

	
	//判断是否为空
	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return (count == 0);
	}

	 
	//set的长度
	@Override
	public int size() {
		// TODO Auto-generated method stub
		return count;
	}

	//返回set的迭代器
	@Override
	public Iterator<T> iterator() {
		// TODO Auto-generated method stub
		return new LinkedIterator<T>(contents,count);
	}

}

在返回迭代器的时候,我们又新定义了一个类,用来生成迭代器

代码如下:

package linkedset;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LinkedIterator<T> implements Iterator<T> {
	
	private int count;
	private LinearNode<T> current;
	
	public LinkedIterator(LinearNode<T> collection ,int size){
		current = collection;
		count = size;
	}
	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		return (current != null);
	}

	@Override
	public T next() {
		// TODO Auto-generated method stub
		if(!hasNext()){
			throw new NoSuchElementException();
		}
		T result = current.getElement();
		current = current.getNext();
		return result;
	}

}

好,接下来就可以测试是否成功了

package linkedset;

public class LinkedSetTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedSet<Integer> test = new LinkedSet<Integer>();
		test.add(14);
		test.add(24);
		test.add(34);
		test.add(35);
		test.remove(35);
		test.display();
		System.out.print("\n+++++++++++++++++++++++++++++\n");
		test .add(34);
		test.display();
		System.out.println();
		System.out.println(test.size());
		System.out.println(test.isEmpty());
		LinkedSet<Integer> test2 = new LinkedSet<Integer>();
		test2.add(433);
		test2.add(345);
		test2.add(211);
		test2.add(64);
		test2.add(34);
	//	test.addAll(test2);
		test.display();
		
		System.out.println();
		System.out.println(test.size());
		
		LinkedSet<Integer> test3 = new LinkedSet<Integer>();
		test3.add(14);
		test3.add(24);
		test3.add(34);
		System.out.println();
		System.out.println("++++++++++++++++++++++++++++++++++++++++\n");
		test3.display();
		System.out.println();
		System.out.println(test.equals(test2));
		System.out.println(test.equals(test3));
	}

}



OK,方法可用,成功。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值