`
┿┅мīSS
  • 浏览: 96009 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

集合操作类--包(单向链表实现)

    博客分类:
  • J2SE
阅读更多
节点类
package com.opensource.nodes;

/**
 * 一个IntNode为链表提供一个节点,每个节点包含整形数据。链表可以具有任何长度,
 * 仅受堆中空闲内存空间的限制。但是当超出Integer.MAX_VALUE时,listLengh将
 * 因为算术溢出而不正确
 */
public class IntNode 
{
	private int data;  //储存在这个节点中的元素
	private  IntNode link; //指向链表中的下一个节点
	
	public IntNode(int initialData,IntNode initialLink)
	{
		data = initialData;
		link = initialLink;
	}
	
	/**
	 * 在当前节点之后添加新节点
	 * @param element  
	 */
	public void addNodeAfter(int element)
	{
		link =new IntNode(element,link);
	}
	
	/**
	 * 获取节点中储存的数值
	 * @return
	 */
	public int getData()
	{
		return data;
	}
	
	/**
	 * 获取指向当前节点的下一个节点的指针
	 */
	public IntNode getLink()
	{
		return link;
	}
	
	/**
	 * 复制链表
	 * @param source 将要复制的链表的头指针
	 * @return
	 */
	public static IntNode listCopy(IntNode source)
	{
		IntNode copyHead;
		IntNode copyTail;
		
		if(source == null)
			return null;
		
		copyHead = new IntNode(source.data,null);
		copyTail = copyHead;
		while(source.link != null)
		{
			source = source.link;
			copyTail.addNodeAfter(source.data);
			copyTail = copyTail.link;
		}
		
		return copyHead;
	}
	
	/**
	 * 复制链表,同时返回副本的头指针和为指针
	 * @param source  将要复制的链表的头指针
	 * @return
	 */
	public static IntNode[] listCopyWithTail(IntNode source)
	{
		IntNode copyHead;
		IntNode copyTail;
		IntNode[] answer = new IntNode[2];
		
		if(source == null)
			return null;
		
		copyHead = new IntNode(source.data , null);
		copyTail = copyHead;
		while(source.link != null)
		{
			source = source.link;
			copyTail.addNodeAfter(source.data);
			copyTail = copyTail.link;
		}
		answer[0] = copyHead;
		answer[1] = copyTail;
		
		return answer;
	}
	
	/**
	 * 获取链表的长度
	 * @param head 
	 * @return
	 */
	public static int listLength(IntNode head)
	{
		IntNode cursor;
		int answer = 0;
		for(cursor = head;cursor !=null;cursor = head.link)
		{
			answer++;
		}
		
		return answer;
	}
	
	/**
	 * 复制链表的一部分,同时提供副本的头指针和尾指针
	 * @param start
	 * @param end
	 * @return
	 */
	public static IntNode[] listPart(IntNode start, IntNode end)
	{
		IntNode copyHead;
		IntNode copyTail;
		IntNode[] answer = new IntNode[2];
		
		if(start == null)
			throw new IllegalArgumentException("start is null");
		if(end == null)
			throw new IllegalArgumentException("end is null");
		
		copyHead = new IntNode(start.data,null);
		copyTail = copyHead;
		while(start != end)
		{
			start = start.link;
			if(start ==null)
				throw new IllegalArgumentException
				  ("end node was not found on the list");
			copyTail.addNodeAfter(start.data);
			copyTail = copyTail.link;
		}
		answer[0] = copyHead;
		answer[1] = copyTail;
		return answer;
	}
	
	/**
	 * 查找位于链表中特定位置的节点
	 * @param head
	 * @param position
	 * @return
	 */
	public static IntNode listPosition(IntNode head,int position)
	{
		IntNode cursor;
		int i;
		
		if(position <= 0)
			throw new IllegalArgumentException("position is not positive.");
		cursor = head;
		for(i = 1;(i < position)&&(cursor != null);i++)
			cursor = cursor.link;
		
		return cursor;
	}
	
	/**
	 * 查找链表中的特定数据
	 * @param head
	 * @param target
	 * @return
	 */
	public static IntNode listSearch(IntNode head,int target)
	{
		IntNode cursor;
		for(cursor = head;cursor != null;cursor = cursor.link)
		{
			if(target == cursor.data)
				return cursor;
		}
		return null;
	}
	
	/**
	 * 删除当前节点的下一个节点
	 */
	public void removeAfter()
	{
		link = link.link;
	}
	
	/**
	 * 设置当前节点中的数据
	 * @param newData
	 */
	public void setData(int newData)
	{
		data = newData;
	}
	
	/**
	 * 设置指向当前节点的下一个节点的指针
	 * @param newLink
	 */
	public void setLink(IntNode newLink)
	{
		link = newLink;
	}
}



包操作类
package com.opensource.collections;

import com.opensource.nodes.IntNode;

/**
 * 整形集合元素操作
 * 单向链表实现
 */
public class IntLinkedBag implements Cloneable 
{
	//包ADT的不变式:
	//1.包中的元素存储在链表中.
	//2.链表的头指针位于实例变量head中.
	//3.链表中的元素总数位于实例变量manyNodes;
	
	private IntNode head;  //链表的头指针
	private int manyNodes; //链表的节点数
	
	public IntLinkedBag()
	{
		head = null;
		manyNodes = 0;
	}
	
	/**
	 * 添加一个新元素到包中
	 * @param element
	 */
	public void add(int element)
	{
		head = new IntNode(element,head);
		manyNodes++;
	}
	
	/**
	 * 将另一个包中的内容添加到当前包中
	 * @param addend
	 */
	public void addAll(IntLinkedBag addend)
	{
		IntNode[] copyInfo;
		if(addend == null)
			throw new IllegalArgumentException("addend is null.");
		if(addend.manyNodes > 0)
		{
			copyInfo = IntNode.listCopyWithTail(addend.head);
			copyInfo[1].setLink(head);
			head = copyInfo[0];
			manyNodes += addend.manyNodes;
		}
	}
	
	/**
	 * 生成当前包的副本
	 */
	public Object clone()
	{
		IntLinkedBag answer;
		try
		{
			answer = (IntLinkedBag)super.clone();
		}catch(CloneNotSupportedException e)
		{
			throw new RuntimeException
			  ("This class does not implement Cloneable.");
		}
		answer.head = IntNode.listCopy(head);
		
		return answer;
	}
	
	/**
	 * 统计特定元素在当前包中出现的次数
	 * @param target
	 * @return
	 */
	public int countOccurrences(int target)
	{
		int answer = 0;
		IntNode cursor = IntNode.listSearch(head, target);
		while(cursor != null)
		{
			answer++;
			cursor = cursor.getLink();
			cursor = IntNode.listSearch(cursor, target);
		}
		
		return answer;
	}
	
	/**
	 * 从当前包中检索一个随机元素
	 * @return
	 */
	public int grab()
	{
		int i;
	    IntNode cursor;
	    
	    if(manyNodes == 0)
	    	throw new IllegalArgumentException("Bag size is zero.");
	    i = (int)(Math.random()*manyNodes+1);
	    cursor = IntNode.listSearch(head, i);
	    return cursor.getData();
	}
	
	/**
	 * 从包中指定元素
	 * @param target
	 * @return
	 */
	public boolean remove(int target)
	{
		IntNode targetNode;
		targetNode = IntNode.listSearch(head, target);
		if(targetNode == null)
			return false;
		else
		{
			targetNode.setData(head.getData());
			head = head.getLink();
			manyNodes--;
			return true;
		}
	}
	
	/**
	 * 获取当前包中元素的个数
	 * @return
	 */
	public int size()
	{
		return manyNodes;
	}
	
	/**
	 * 创建一个新包,它包含来自其他两个包中的所有元素
	 * @param b1
	 * @param b2
	 * @return
	 */
	public static IntLinkedBag union(IntLinkedBag b1,IntLinkedBag b2)
	{
		if(b1 == null)
			throw new IllegalArgumentException("b1 is null.");
		if(b2 == null)
			throw new IllegalArgumentException("b2 is null.");
		IntLinkedBag answer = new IntLinkedBag();
		answer.addAll(b1);
		answer.addAll(b2);
		return answer;
	}
}

分享到:
评论

相关推荐

    单向链表类模板(全)C++

    在C++编程中,单向链表是一种基本的数据结构,用于存储动态集合。单向链表的特点是每个节点包含一个数据元素和一个指向下一个节点的指针,最后一个节点的指针为空。本压缩包文件提供了实现单向链表类模板的完整代码...

    flash as3.0 实现的单向链表

    总结起来,Flash AS3.0实现的单向链表是一个很好的学习和实践数据结构的例子,它包含了链表的基本操作,有助于提升对链表的理解和编程能力。在AS3.0项目中,可以利用这样的链表类来优化数据管理,特别是在处理动态...

    C/C++实现单向链表

    单向链表是一种基本的数据结构,它在计算机科学中被广泛使用,特别是在处理动态数据集合时。本项目中,我们分别使用C语言和C++语言实现了单向链表的几个核心功能,包括创建链表、插入数据、获取指定位置的数据以及...

    c#单向链表的实现

    总结来说,C#中的单向链表是通过自定义的Node类和SinglyLinkedList类来实现的。Node类表示链表中的一个节点,包含数据和指向下一个节点的引用。SinglyLinkedList类提供了各种操作链表的方法,如添加、插入、删除和...

    单向循环链表.zip

    单向循环链表是一种常见的数据结构,它在计算机科学中有着广泛的应用,特别是在实现动态数据集合,如列表或队列时。在这个压缩包文件“单向循环链表.zip”中,包含了两个源代码文件——LoopSingle.java和List.java,...

    链表-使用Python实现链表数据结构.zip

    链表是一种基础且重要的数据结构,它在计算机科学中扮演着关键角色,特别是在处理动态数据...通过这个“链表-使用Python实现链表数据结构”的资源,你可以深入了解链表的工作原理,并练习使用Python来创建和操作链表。

    实现泛型类集合 实现双向链表

    相比单向链表,双向链表提供了更灵活的遍历方式,可以从前往后也可以从后往前。实现双向链表需要定义一个节点类(Node),以及链表类(DoubleLinkedList): ```java public class Node&lt;T&gt; { private T data; ...

    c++链表编程实现代码

    单向链表是最基础的链表形式,每个节点包含一个数据部分和一个指向下一个节点的指针。在C++中,我们可以定义一个结构体或类来表示链表节点,如`struct Node { int data; Node* next; }`。插入、删除和遍历操作都...

    数据结构单向链表

    单向链表是一种基本的数据结构,它在计算机科学和编程中有着广泛的应用,尤其是在处理动态数据集合时。本文将深入探讨C++实现的单向链表,并将其与数据结构和链表的概念相结合。 首先,我们要理解什么是数据结构。...

    用VC++实现的单向和双向链表

    在C++中,链表可以被实现为类结构,以支持单向链表和双向链表两种形式。这里我们将深入探讨如何用VC++实现这两种链表。 首先,我们来理解链表的基本概念。链表不同于数组,它不是连续存储数据的结构。每个链表节点...

    链表是常用数据结构之一 ,总体分为单向 ,双向

    链表分为两大类:单向链表和双向链表,每种都有其独特的特性和用途。 1. 单向链表: - 定义:单向链表中的每个节点包含两部分,一部分存储数据,另一部分称为指针或链接,指向下一个节点。链表的最后一个节点的...

    链表-使用PHP实现的双向链表数据结构.zip

    双向链表是链表的一种变体,与单向链表不同,它允许从两个方向遍历链表。每个节点除了包含数据和指向下一个节点的指针外,还有一个指向前一个节点的指针。这样的设计提高了数据操作的灵活性,例如在链表中间插入或...

    易语言链表操作类源码

    单向链表的每个节点只有一个指向下一个节点的指针,而双头链表则有两个指针,一个指向前一个节点,一个指向后一个节点。这样的设计使得在链表的头部和尾部进行操作更加方便,提高了代码的效率。 源码可能包含以下...

    java 数据结构 链表

    - 插入和删除操作:相比于单向链表,双向链表在插入和删除操作时可以更高效,因为可以从两个方向查找节点。 - 遍历操作:双向链表可以从前向后或从后向前遍历。 Java API中提供了一个名为`LinkedList`的内置类,...

    数据结构—刘小晶—例2.7-用链表结构写的学生成绩管理系统

    总的来说,刘小晶教授的例2.7通过一个实际的应用场景,让我们直观地理解了链表数据结构在处理动态数据集合时的优势,以及如何在Java中实现链表结构和相关操作。通过这样的实践,我们可以加深对数据结构的理解,提升...

    VB中实现链表

    在VB(Visual Basic)中,虽然没有内置的链表类,但可以通过自定义数据类型和对象来实现链表的操作。以下是对VB中实现链表相关知识点的详细说明。 首先,链表的基本概念是节点(Node),每个节点包含两部分:数据域...

    数据结构 -- 链表的基本操作

    链表的类型主要有单向链表、双向链表和循环链表。 1. 插入操作: - 在链表头部插入:这是最快的方式,因为只需更新头节点即可。创建新节点,将新节点的数据域设置为要插入的元素,指针域指向原头节点,然后将头...

    Java集合,HashMap底层实现和原理(1.7数组+链表与1.8+的数组+链表+红黑树) 数组和链表.pdf

    Java集合,HashMap底层实现和原理(1.7数组+链表与1.8+的数组+链表+红黑树) 在Java集合中,HashMap是一个常用的数据结构,它基于Map接口实现,元素以键值对的方式存储,并且允许使用null键和null值。由于key不允许...

    链表类的使用

    单向链表的每个节点只能向前引用下一个节点,而双向链表的节点可以向前和向后引用。 3. **操作效率**:链表插入和删除操作通常比数组更快,因为它们只需要改变几个指针,而不需要移动大量的数据。 ### `CPtrList`类...

    python单向链表的基本操作细节(小白入门)

    【Python 单向链表的基本操作细节】 链表是一种数据结构,它不同于数组,它将数据元素分散在内存的不同位置,而不是连续存储。单向链表是链表的一种形式,其中每个节点包含一个数据元素和一个指向下一个节点的引用...

Global site tag (gtag.js) - Google Analytics