数据结构(Java语言)——LinkedList

以下是一个可以使用的LinkedList泛型类的实现。这里的链表类名为MyLinkedList,避免与类库中重复。

MyLinkedList将作为双链表实现,而且保留到该表两端的引用。这样只要操作发生在已知的位置,就可以保持每个操作花费常数时间的代价。这个已知的位置可以是端点,也可以是由迭代器指定的一个位置。

设计方面,主要分为三个部分实现:

  1. MyLinkedList类本身,包含到两端的链、表的大小以及一些方法。
  2. Node类,它可能是一个私有的嵌套类。一个节点包含数据以及到前一个节点的链和到下一个节点的链,还有一些适当的构造方法。
  3. LinkedListIterator类,该类抽象了位置的概念,是一个私有类,并实现接口Iterator。包含方法next(),hasNext(),remove()的实现。
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyLinkedList<AnyType> implements Iterable<AnyType> {
	private int theSize;
	private int modCount = 0;
	private Node<AnyType> beginMarker;
	private Node<AnyType> endMarker;

	private static class Node<AnyType> {
		public AnyType data;
		public Node<AnyType> prev;
		public Node<AnyType> next;

		public Node(AnyType d, Node<AnyType> p, Node<AnyType> n) {
			data = d;
			prev = p;
			next = n;
		}
	}

	public MyLinkedList() {
		clear();
	}

	public void clear() {
		beginMarker = new Node<AnyType>(null, null, null);
		endMarker = new Node<AnyType>(null, beginMarker, null);
		beginMarker.next = endMarker;
		theSize = 0;
		modCount++;
	}

	public int size() {
		return theSize;
	}

	public boolean isEmpty() {
		return size() == 0;
	}

	public void add(AnyType x) {
		add(size(), x);
	}

	public void add(int idx, AnyType x) {
		addBefore(getNode(idx), x);
	}

	public AnyType get(int idx) {
		return getNode(idx).data;
	}

	public AnyType set(int idx, AnyType newVal) {
		Node<AnyType> p = getNode(idx);
		AnyType oldVal = p.data;
		p.data = newVal;
		return oldVal;
	}

	public AnyType reomve(int idx) {
		return remove(getNode(idx));
	}

	private void addBefore(Node<AnyType> p, AnyType x) {
		Node<AnyType> newNode = new Node<AnyType>(x, p.prev, p);
		newNode.prev.next = newNode;
		p.prev = newNode;
		theSize++;
		modCount++;
	}

	private AnyType remove(Node<AnyType> p) {
		p.next.prev = p.prev;
		p.prev.next = p.next;
		theSize--;
		modCount++;
		return p.data;
	}

	private Node<AnyType> getNode(int idx) {
		Node<AnyType> p;
		if (idx < 0 || idx > size()) {
			throw new IndexOutOfBoundsException();
		}
		if (idx < size() / 2) {
			p = beginMarker.next;
			for (int i = 0; i < idx; i++) {
				p = p.next;
			}
		} else {
			p = endMarker;
			for (int i = size(); i < idx; i--) {
				p = p.prev;
			}
		}
		return p;
	}

	public Iterator<AnyType> iterator() {
		return new LinkedListIterator();
	}

	private class LinkedListIterator implements Iterator<AnyType> {
		private Node<AnyType> current = beginMarker.next;
		private int expectedModCount = modCount;
		private boolean okToRemove = false;

		@Override
		public boolean hasNext() {
			return current != endMarker;
		}

		@Override
		public AnyType next() {
			if (modCount != expectedModCount) {
				throw new ConcurrentModificationException();
			}
			if (!hasNext()) {
				throw new NoSuchElementException();
			}
			AnyType nextItem = current.data;
			current = current.next;
			okToRemove = true;
			return nextItem;
		}

		public void remove() {
			if (modCount != expectedModCount) {
				throw new ConcurrentModificationException();
			}
			if (!okToRemove) {
				throw new IllegalStateException();
			}
			MyLinkedList.this.remove(current.prev);
			okToRemove = false;
			expectedModCount++;
		}
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 18:04:30

数据结构(Java语言)——LinkedList的相关文章

数据结构(java语言描述)顺序栈的使用(两个大数相加)

利用http://www.cnblogs.com/xleer/p/5289661.html中对顺序栈以及栈的进本方法的定义,实现超过整数上限的两个数的加法计算. 算法: package stack;/********************************************************************** * @author sch ********利用栈,计算两个大数的和.大数的值超过int存储的范围******************************

数据结构(java语言描述)链栈的定义

1.定义栈接口 package stack;public interface Istack {    public void clear();    public boolean isEmpty();    public int length();    public Object peek();    public void push(Object x) throws Exception;    public Object pop();} 2.定义Node结点 package stack; i

数据结构(java语言描述)递归实现——汉诺塔问题

1.汉诺塔问题描述 N阶汉诺塔:假设有3个分别命名为x,y,z的三个塔座,在x上有n个盘子,直径大小不同,有小到大按标号1,2,3...n排列,要借助y将n个盘子转移到z上,期间不能让小盘子压在大盘子上.规则: 每次至移动一个盘子: 盘子可以插在x,y,z任意一个塔座上: 任何时候都不能将大盘压在小盘上. 2.解题思路 当n=1时,直接把盘子由x——>z; 当n>1时,需利用y,首先将(n-1)个盘子由x——>y,把第n个实现x——>z,然后把问题转换为实现(n-1)个盘子由y——

数据结构(java语言描述)哈夫曼编码

原理:哈夫曼编码是根据将已给出的权值作为叶子结点,生成一颗哈夫曼树,然后使得权重最小. 首先生成已给权重的所有的叶子结点,然后取所有节点中最小和次小的结点作为左右孩子生成一个哈夫曼树,计算出父节点的权重放入给出的权重森林中,并把之前的最小和次小的结点从森林中删除,再在种种森林中找最小和次小的结点生成权重树....直到最终只剩下一个树为止. 哈夫曼树的结点用如下结点表示: (有权重,左右孩子,父节点,然后设置一个标识符标志结点是否已经放入哈夫曼树) package tree;/**********

【数据结构】之队列(Java语言描述)

在[这篇文章]中,我简单介绍了队列的基本数据结构及操作方式,并用C语言代码描述了队列的基本功能实现. JDK中默认为我们提供了队列的API-- Queue . Queue是一个接口,其中提供了处理队列及其操作的一些基本方法,如果我们想要创建自己的队列,就需要先创建一个类实现Queue接口. 在Java语言中也为我们提供了一些现成的Queue接口的实现类,如下: * @see java.util.Collection * @see LinkedList * @see PriorityQueue *

数据结构(Java语言)——HashTable简单实现

散列表的实现通常叫做散列hashing.散列是一种用于以常数平均时间执行插入.删除和查找的技术.但是,那些需要元素间任何排序信息的树操作将不会得到有效的支持.理想的散列表数据结构只不过是一个包含一些项的具有固定大小的数组.通常查找是对项的某个部分(数据域)进行的,这部分叫做关键字.例如,项可以由一个串(作为关键字)和其它一些数据域组成.我们把表的大小记作TableSize,并将其理解为散列数据结构的一部分,而不仅仅是浮动于全局的的某个变量.通常习惯是让表从0到TableSize-1变化. 每个关

数据结构与问题求解-Java语言描述(第三版)

数据结构对程序的重要性不言而喻,用java语言来实现常见的一些数据结构,以及在相应数据结构上的操作对学习java的同学来说是必须掌握的. 本系列博文参考<数据结构与问题求解-Java语言描述(第三版)>来实现 在自己学习的过程中,更希望有机会与大家交流. PS :本人是菜鸟,只是用博客的方式激励自己.请轻喷.Fighting!

【数据结构】之顺序表(Java语言描述)

之前总结过使用C语言描述的顺序表数据结构.在C语言类库中没有为我们提供顺序表的数据结构,因此我们需要自己手写,详细的有关顺序表的数据结构描述和C语言代码请见[我的这篇文章]. 在Java语言的JDK中,为我们提供了专门的顺序表的数据结构API-- ArrayList . Java中的ArrayList的基本存储思路和C语言中的思路相似,即将所有元素存储在一个数组中,当数组中的元素个数达到某种标准时,就要扩容.由于顺序表中的其他操作在Java和C中的实现方式大同小异,因此,本文不再详细介绍这些操作

C--c语言模拟java的linkedList

java的linkedList集合,是一个单链集合,因此只需要知道头,便知道后边接着的全部. 第一步:先把头文件写好 linkedList.h //这是头文件 struct person { int value; struct person * next; }; typedef struct person p; /*addLast从最后一个处添加. 先判断头在不在, 如果头在的话,就循环判断知道找到最后一个,创建实例,添加至最后一个的后面位置处 */ void addLast(p* head,i

java通过LinkedList实现堆栈和队列数据结构

1 package com.shb.java; 2 3 import java.util.LinkedList; 4 5 public class TestLinkedList { 6 7 /** 8 * @author shaobn 9 * @Describe :利用LinkedList实现队列和堆栈 10 * @param args 11 * @Time : 2015-8-27 下午10:28:33 12 */ 13 public static void main(String[] args