单向循环链表

单向循环链表:

什么是单向循环链表?
如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是把尾节点的下一跳指向头结点。
为什么要使用单向循环链表?
在单向链表中,头指针是相当重要的,因为单向链表的操作都需要头指针,所以如果头指针丢失或者破坏,那么整个链表都会遗失,并且浪费链表内存空间,因此我们引入了单向循环链表这种数据结构。
如下图所示:
单向循环链表_第1张图片
单向循环链表我们需要注意一个问题:
在链表中我们使用的是虚拟头结点,但是在循环链表中我们在遍历的时候就会遇到麻烦,因此在单向循环链表中我们使用的是真实头结点。
具体的实现示意图如下图所示:
单向循环链表的插入:

单向循环链表_第2张图片
单向循环链表的插入与单向链表有所不同,因为单向循环链表首尾相连,所以没有从尾部插入的问题。
(1)从链表头部插入
将新插入的节点变为链表头部,next指向原来的第一个节点,在遍历整个链表找到链表末尾(即它的next指向的是head的那个节点),将这个节点的next指向新插入的节点,最后再将链表头指针指向新节点。
(2)从链表中间插入
此时插入的过程和单向链表的一样,找到要插入位置前驱节点,将前驱节点的next指向新节点的next,再将前驱节点的next指向新插入的节点。
单向循环链表的类图如下图所示:
单向循环链表_第3张图片
具体代码实现如下图所示:

public class LoopSingle implements List {
	
	private class Node {
		E data;
		Node next;
		
		public Node(E data,Node next) {
			this.data = data;
			this.next = next;
		}
	}
	
	private Node head;
	private Node rear;
	private int size;
	
	public LoopSingle() {
		head = new Node(null, null);
		rear = head;
		size = 0;
	}
	
	public Node getNode() {
		return head;
	}
	
	public LoopSingle(E[] arr) {
		// TODO Auto-generated method stub
	}

	@Override
	public int getSize() {
		return size;
	}

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

	@Override
	public void add(int index, E e) {
		if(index<0 || index>size) {
			throw new IllegalArgumentException("插入下标非法");
		}
		if(size==0) {
			head = new Node(e, null);
			rear = head;
			rear.next = head;
		} else if(index==0) {
			Node n = new Node(e, head);
			rear.next = n;
			head = n;
		} else if(index==size) {
			Node n = new Node(e, head);
			rear.next = n;
			rear = n;
		} else {
			Node p = head;
			for(int i=0;i=size) {
			throw new IllegalArgumentException("查询下标非法");
		}
		Node p = head;
		for(int i=0;i=size) {
			throw new IllegalArgumentException("修改下标非法");
		}
		Node p = head;
		for(int i=0;i=size) {
			throw new IllegalArgumentException("删除下标非法");
		}
		E e = null;
		Node n;
		if(size==1) {
			e = head.data;
			clear();
		} else if(index==0) {
			n = head;
			e = head.data;
			rear.next = head.next;
			head = head.next;
			n.next = null;
		} else if(index==size-1) {
			e = rear.data;
			n = rear;
			Node p = head;
			while(p.next!=rear) {
				p = p.next;
			}
			p.next = head;
			rear = p;
			n.next = null;
		} else {
			Node p = head;
			for(int i=0;i loop = (LoopSingle) obj;
			if(getSize()==loop.getSize()) {
				Node n = head;
				Node p = loop.head;
				for(int i=0;i

你可能感兴趣的:(数据结构)