`
baby69yy2000
  • 浏览: 187841 次
  • 性别: Icon_minigender_1
  • 来自: 自己输入城市...
社区版块
存档分类
最新评论

数据结构 Java循环双向链表

    博客分类:
  • Util
阅读更多
■ 构造函数
每个构造函数都通过 this 来初始化链接域 prev 和 next.图⑴
prev = this; next = this;

■ 判断表空的条件
public boolean isEmpty() {
		return (header.prev == header || header.next == header);
}

图⑴



■ addBefore 方法是 MyLinkedList 类的重要方法, 后面的很多方法都要依靠它来实现!图⑵
	private static <T> DNode<T> addBefore(DNode<T> curr, T item) {
		DNode<T> newNode, prevNode;

		newNode = new DNode<T>(item);
		
		prevNode = curr.prev;
		
		newNode.prev = prevNode; ①
		newNode.next = curr; ②
		
		prevNode.next = newNode; ③
		curr.prev = newNode; ④
     return newNode;
	}

图⑵


■ addFirst方法就是靠addBefore来实现的!
因为
header.next = nd'  -->图⑵
所以
curr = nd'  --> addBefore()方法
因此
prevNode = curr.prev = h  --> addBefore()方法
继续重复这四句话
newNode.prev = prevNode; ①
newNode.next = curr; ②
prevNode.next = newNode; ③
curr.prev = newNode; ④

public void addFirst(T item) {
		addBefore(header.next, item);
		listSize++;
}

图⑶


■ remove方法也很重要!
private void remove(DNode<T> curr) {
		if(curr.next == curr) return;
		
		DNode<T> prevNode = curr.prev, nextNode = curr.next;
		
		prevNode.next = nextNode;
		nextNode.prev= prevNode;
}


package LinkedList;

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

public class MyLinkedList<T> {
	//*************************************************************
	private DNode<T> header;
	private int listSize;
	//*************************************************************
	public MyLinkedList() {
		header = new DNode<T>();
		listSize = 0;
	}
	//*************************************************************
	private static class DNode<T> {
		T nodeValue;
		DNode<T> prev;
		DNode<T> next;

		public DNode() { // for header
			nodeValue = null;
			prev = this; // left
			next = this; // right
		}

		public DNode(T item) {
			nodeValue = item;
			prev = this;
			next = this;
		}
	}
	//**************************************************************
	public boolean isEmpty() {
		return (header.prev == header || header.next == header);
	}
	
	public int size() {
		return listSize;
	}
	//**************************************************************
	private DNode<T> addBefore(DNode<T> curr, T item) {
		DNode<T> newNode, prevNode;

		newNode = new DNode<T>(item);
		
		prevNode = curr.prev;
		
		newNode.prev = prevNode;
		newNode.next = curr;
		
		prevNode.next = newNode;
		curr.prev = newNode;

		return newNode;
	}

	public boolean add(T item) {
		addBefore(header, item);
		listSize++;
		return true;
	}
	
	public void addFirst(T item) {
		addBefore(header.next, item);
		listSize++;
	}
	
	public void addLast(T item) {
		addBefore(header, item);
		listSize++;
	}
	//**************************************************************
	private void remove(DNode<T> curr) {
		if(curr.next == curr) return;
		
		DNode<T> prevNode = curr.prev, nextNode = curr.next;
		
		prevNode.next = nextNode;
		nextNode.prev= prevNode;
	}
	
	public boolean remove(Object o) {
		for(DNode<T> p = header.next; p != header; p = p.next) {
			if(o.equals(p.nodeValue)) {
				remove(p);
				listSize--;
				return true;
			}
		}
		return false;
	}
	//**************************************************************
	public void printList() {
		for(DNode<T> p = header.next; p != header; p = p.next)
			System.out.println(p.nodeValue);
	}
	//**************************************************************
	private class MyIterator implements Iterator<T> {
		
		public DNode<T> nextNode = header.next;
		public DNode<T> lastReturned = header;
		
		public boolean hasNext() {
			return nextNode != header;
		}
		
		public T next() {
			if(nextNode == header)
				throw new NoSuchElementException("");
			
			lastReturned = nextNode;
			nextNode = nextNode.next;
			return lastReturned.nodeValue;
		}

		public void remove() {
			if(lastReturned == header)
				throw new IllegalStateException("");
			
			MyLinkedList.this.remove(lastReturned);
			lastReturned = header;
			listSize--;
		}
	}
	//**************************************************************
	private class MyListIterator extends MyIterator implements ListIterator<T> {
		
		private int nextIndex;
		
		MyListIterator(int index) {
			if(index < 0 || index > listSize)
				throw new IndexOutOfBoundsException("");
			
			//如果index小于listSize/2,就从表头开始查找定位,否则就从表尾开始查找定位
			if(index < (listSize >> 1)) {
				nextNode = header.next;
				for(nextIndex = 0; nextIndex < index; nextIndex++)
					nextNode = nextNode.next;
			}else {
				nextNode = header;
				for(nextIndex = listSize; nextIndex > index; nextIndex--)
					nextNode = nextNode.prev;
			}
		}

		public boolean hasPrevious() {
			return nextIndex != 0;
			//return nextNode.prev != header;
		}
		
		public T previous() {
			if (nextIndex == 0)
				throw new NoSuchElementException("no");
			
			lastReturned = nextNode = nextNode.prev;
			nextIndex--;
			return lastReturned.nodeValue;
		}
		
		public void remove() {
			if(lastReturned == header)
				throw new IllegalStateException("");
			
			MyLinkedList.this.remove(lastReturned);
			nextIndex--;
			listSize--;
			
			if(lastReturned == nextNode)
				nextNode = nextNode.next;
			lastReturned = header;
		}
		
		public void add(T item) {
			MyLinkedList.this.addBefore(nextNode, item);
			nextIndex++;
			listSize++;
			lastReturned = header;
		}
		
		public void set(T item) {
			 if (lastReturned == header)
				 throw new IllegalStateException();
			 
			 lastReturned.nodeValue = item;
		}
		
		public int nextIndex() {
			return nextIndex;
		}

		public int previousIndex() {
			return nextIndex - 1;
		}
	}
	
	//**************************************************************
	public Iterator<T> iterator() {
		return new MyIterator();
	}
	//**************************************************************
	public ListIterator<T> listIterator(int index) {
		return new MyListIterator(index);
	}
	//**************************************************************
	public static void main(String[] args) {
		MyLinkedList<String> t = new MyLinkedList<String>();
		t.add("A");
		t.add("B");
		t.add("C");
		t.add("D");
		//t.remove("B");
		//t.addFirst("AA");
		//t.addLast("BB");
		//t.printList();
		/*
		Iterator<String> it = t.iterator();
		while(it.hasNext()) System.out.println(it.next()); // A B C D
		*/
		
		ListIterator<String> it = t.listIterator(t.size());
		
		while(it.hasPrevious()) {
			System.out.println(it.previous()); // D C B A
		}
	}

}// MyLinkedList end~

分享到:
评论

相关推荐

    Java有序非循环双向链表算法实例

    在Java编程中,有序非循环双向链表是一种重要的数据结构,它在许多复杂的数据操作和算法实现中扮演着核心角色。有序意味着链表中的元素按照特定的顺序排列,非循环则表示链表的首节点和尾节点之间没有链接,使得遍历...

    基于java的循环双链表

    总的来说,通过Java实现循环双链表需要对面向对象编程、数据结构以及链表操作有深入理解。这是一个很好的练习,可以帮助开发者提高对Java特性和数据结构设计的理解。在编写代码时,一定要注意处理好边界条件和循环...

    数据结构 DataStructure(单链表和循环双链表)

    在"my DataStructure"的压缩包中,可能包含了用某种编程语言(如C、C++、Java或Python)实现的单链表和循环双链表的数据结构代码。这些代码可能包括了节点定义、链表的初始化、插入、删除、遍历等基本操作。通过阅读...

    带头结点的双向循环链表数据结构

    【带头结点的双向循环链表数据结构】 在数据结构中,双向循环链表是一种特殊类型的数据结构,它允许从两个方向遍历链表。在本案例中,我们需要使用C++和Java分别实现这种数据结构,并确保它们符合指定的要求。 在...

    双向循环链表

    用java语言将双向链表和循环链表结合起来,数据结构吧课程设计的题目

    简单的双向循环链表

    在编程领域,数据结构是构建高效算法的基础,而链表作为一种基本的数据结构,常常被用于实现各种...`LinkedList.java`提供了实现双向循环链表的模板,读者可以通过阅读和分析源码,进一步加深对这一数据结构的理解。

    JAVA 数据结构链表操作循环链表

    在Java编程中,数据结构是程序设计的基础,链表是一种常用的数据结构,它不依赖于数组的物理位置,而是通过节点间的引用关系进行组织。循环链表是链表的一种变体,它的特点是最后一个节点指向了链表的第一个节点,...

    java双向循环链表实现程序_.docx

    Java 双向循环链表是一种数据结构,它包含前后两个指针,每个节点都有一个指向其前一个节点的引用和一个指向其后一个节点的引用。这种数据结构允许我们在链表的任何位置进行高效的插入和删除操作。在给定的程序中,...

    基于java数据结构链表实验报告.pdf

    Java数据结构链表实验报告 Java数据结构链表实验报告是基于Java语言编写的实验报告,主要研究了链表的实现和操作。链表是一种基本的数据结构,广泛应用于计算机科学和软件开发中。本实验报告涵盖了链表的存储结构、...

    java实现的单向链表和双向链表

    本篇将深入探讨由Java实现的单向链表和双向链表。 首先,我们来理解单向链表。单向链表中的每个节点包含两部分:数据域(存储实际数据)和指针域(存储指向下一个节点的引用)。这种结构使得链表只能向前遍历,不能...

    长正整数相减(数据结构-循环链表)

    //定义链表结构 NODE *inputint(void){ //输入超长整数,存入链表 } NODE *insert_after(NODE *u,int num){ //在u结点后插入一个新的NODE,其值为num } int compare(NODE *p,NODE *q){ //比较两个数的大小 } ...

    java双向循环链表实现程序__1.docx

    在Java编程中,双向循环链表是一种特殊的数据结构,它包含指向前后节点的引用,使得在链表中进行正向和反向遍历都变得容易。在这个程序中,作者实现了一个名为`BothwayLoopLinked`的类来表示双向循环链表。这个类...

    数据结构-链表 JAVA语言实现

    数据结构-链表 JAVA语言实现,包含单向链表、双向链表、循环链表的遍历、删除和插入 详细介绍:http://blog.csdn.net/z740852294/article/details/77369439

    用JAVA写一个双向循环链表的代码

    酒吧里,一桌人(≥10)围在一起行酒令。酒令如下:先按照顺时针方向从1开始依此数数。若是数到7的倍数或者含有7这个数,则调转方向接着数。依此类推。请模拟此过程。

    Java版链表模板类

    在编程领域,链表是一种非常基础且重要的数据结构,它不同于数组,不需要预先分配连续的内存空间,而是通过节点间的引用关系存储数据。本话题主要关注的是Java中的链表实现,特别是循环链表的模板类设计。循环链表与...

    18.双向链表.wmv(目前数据结构最好的视频,共42集,需要哪一集的知识自己下,一集3积分)

    C++实现 数据结构与算法视频教程 01交换算法 02冒泡排序 03选择排序 04顺序排序 05折半排序 06递归算法 07递归折半查找 08算法_perm 09插入排序 10快速排序 11归并排序 12顺序栈 13顺序队列 14链表的基本概率 15...

    试析用Java实现链表数据结构.pdf

    3. 链表数据结构:介绍了链表的基本概念,包括数据域、指针域、单向链表、双向链表和循环链表的区别。 4. 链表的Java实现:通过具体的Java代码示例,说明了如何实现链表的基本操作,包括创建节点、链表的遍历、删除...

    数据结构(Java版)源代码

    链表有单向链表、双向链表和循环链表等多种形式,适合动态增加或删除元素。 3. **栈**:栈是一种后进先出(LIFO)的数据结构,常用于函数调用、表达式求值等场景。Java中,`java.util.Stack`类提供了栈的操作。 4....

    数据结构代码 栈 链表 队列

    链表分为单向链表、双向链表和循环链表等类型。链表的主要操作有插入、删除和遍历。链表在处理动态数据集合时特别有用,因为它们不需要预先确定大小,且插入和删除操作通常比数组快。 然后是队列(Queue),它是...

Global site tag (gtag.js) - Google Analytics