论坛首页 编程语言技术论坛

非循环单向链表JAVA实现

浏览 1243 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-12-29  

一、自定义迭代器。链表用来存储数据,就必须有访问的数据的工具。代码如下:

import java.util.Iterator;

public interface SingleListIterator<E> extends Iterator<E> {

	boolean hasNext();
	
	E next();
	
	void remove();
	
	void set(E e);
	
	void add(E e);
}

 二、链表实现如下:

import java.util.List;

public class SingleLinkedList<E> extends AbstractSingleLinkedList<E> implements List<E> ,java.io.Serializable {

	private static final long serialVersionUID = -3146637576067909980L;

	private transient Entry<E> header = null;
	private transient int size ;
	// 指向最未端
	private transient Entry<E> lastElement = null;
	
	@Override
	public SingleListIterator<E> singleListIterator() {
		return  new SingleIterator();
	}

	public SingleLinkedList() {
		header = new Entry<E>(null, null);
		lastElement = header;
		size ++;
	}
	
	public E getLast() {
		return lastElement.element;
	}
	
	@Override
	public boolean remove(Object o) {
		boolean result = false;
		if (o == null) {
			for (Entry<E> beforElement = header; beforElement != null; beforElement = beforElement.next) {
				Entry<E> e = beforElement.next;
				if (e != null && e.element == null) {
					beforElement.next = e.next;
					result = true;
					if (e.equals(lastElement)) {
						lastElement = beforElement;
					}
					size --;
				}
			}
		} else {
			for (Entry<E> beforElement = header; beforElement != null; beforElement = beforElement.next) {
				Entry<E> e = beforElement.next;
				if (e != null && o.equals(e.element)) {
					beforElement.next = e.next;
					result = true;
					if (e.equals(lastElement)) {
						lastElement = beforElement;
					}
					size --;
				}
			}
		}
		return result;
	}
	
	@Override
	public E remove(int index) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException("Index: "+index+
                    ", Size: "+size);
		}
		Entry<E> e = header;
		Entry<E> before = header;
		for (int i = 0; i < index; i++) {
			before = before.next;
		}
		e = before.next;
		before.next = e.next;
		if (index == size() -1) {
			lastElement = before;
		}
		size --;
		return e.element;
	}	
	
	@Override
	public void add(int index,E element) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException("Index: "+index+
                    ", Size: "+size);
		}
		Entry<E> e = header;
		Entry<E> before = header;
		for (int i = 0; i < index; i++) {
			before = before.next;
		}
		e = before.next;
		before.next = new Entry<E>(element, e);
		size ++;
	}

	@Override
	public boolean add(E e) {
		lastElement.next = new Entry<E>(e, null); 
		lastElement = lastElement.next;
		size ++;
		return true;
	}
	
	@Override
	public E get(int index) {
		return entry(index).element;
	}
	
	private Entry<E> entry(int index) {
		if (index < 0 || index >= size) {
			throw new IndexOutOfBoundsException("Index: "+index+
                    ", Size: "+size);
		}
		Entry<E> e = header;
		for (int i = 0; i <= index; i++) {
			e = e.next;
		}
		return e;
	}
	
	@Override
	public int size() {
		return size - 1;
	}

	private static class Entry<E> {
		E element;
		Entry<E> next;
		public Entry(E element, Entry<E> next) {
			this.element = element;
			this.next = next;
		}
	}
	
	private class SingleIterator implements SingleListIterator<E> {
		
		// 最后访问的结点
		private Entry<E> lastReturned = header.next;
		// 中间访问的结点
		private Entry<E> beforeElement = header;
		// 最前访问的结点
		private Entry<E> previousElement = beforeElement;
		
		@Override
		public boolean hasNext() {
			// 非循环单链表最后是null
			return lastReturned != null;
		}

		@Override
		public E next() {
			previousElement = beforeElement;
			beforeElement = lastReturned;
			E e = lastReturned.element;
			lastReturned = lastReturned.next;
			return e;
		}

		@Override
		public void remove() {
			previousElement.next = lastReturned;
			// 删除的是中间的结点,删除完后,中间的结点指向最前结点
			beforeElement = previousElement;
			size --;
		}

		@Override
		public void set(E e) {
			beforeElement.element = e;
		}

		@Override
		public void add(E e) {
			// 若前后结点与中单结点相等,是在执行删除后,接着执行add操作
			if (previousElement == beforeElement) {
				previousElement.next = beforeElement = new Entry<E>(e, lastReturned);
			} else {
				previousElement.next = new Entry<E>(e, beforeElement);
			}
			size ++;
		}
	}
}

三、 测试数据如下:

import java.util.ArrayList;
import java.util.List;



public class SingleLinkedListTest {

	public static void main(String[] args) {
		SingleLinkedList<Integer> arr = new SingleLinkedList<Integer>();
		arr.add(456);
		arr.add(789);
		arr.add(0,123);
		arr.add(789);
		arr.add(741);
		//arr.remove(3);
		arr.add(963);
		
		SingleListIterator<Integer> it = arr.singleListIterator();
		
		System.out.println(arr.size());
		
		List<Integer> remove = new ArrayList<Integer>();
		remove.add(789);
		
		while (it.hasNext()) {
			Integer val = it.next();
			if (remove.contains(val)) {
				it.remove();
			}
		}
		
		for (Integer integer : arr) {
			System.out.println(integer);
		}
		
		System.out.println(arr.size());
	}
}

 四、优点:最初的想法是用来锻炼自己的算法设计能力。写完后,发现SingleLinkedList 比 LinkedList 在插入数据的效率略高,理由是:SingleLinkedList 有一个lastElement 变量,指高链表的最后,而 LinkedList 在插入时,要进行循环遍历。

 欢迎大家指点。

论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics