单向循环链表

单向循环链表

        在说单向循环链表前,我们看到这个名字,是不是已经有点想法了。毕竟我们已经学习过循环队列。

        循环队列是在队列的基础上将队列头尾相连,当时我们学习的是顺序存储结构,采用的是下标循环的方法。但现在我们学习的是链式存储结构,而用链式存储结构写循环链表就很简单,只需要将尾结点存储的下一个地址改为头结点即可。

        还有一个小问题,我们之前写的链表,还是基于链表实现的栈、队列,都是采用的是虚拟头结点的方法来实现的,可是我们在实现循环链表时,会发现如果有虚拟头结点,我们在遍历或者插入、删除元素时总是要考虑虚拟头结点的问题。所以今天我们就采用真实头结点来实现循环链表。

        循环列表说白了就是将链表的头尾相连,如下图所示:
在这里插入图片描述
        首先来看一下循环列表的插入动图:

在这里插入图片描述

        上面的动图主要是插入第一个元素和头插、尾插,而一般插入和链表的一般插入是一样的

        下面是循环列表的删除动图:
在这里插入图片描述
        看完基本操作,我们再看类图:
在这里插入图片描述
        好了,接下来,废话就不多说了,直接上代码:

package com.lfz.练习链表;

import com.lfz.练习线性表.List;

public class LoopSingle<E> implements List<E> {
	
	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<index-1;i++) {
				p = p.next;
			}
			Node n = new Node(e, p.next);
			p.next = n;
		}
		size++;
	}

	@Override
	public void addFirst(E e) {
		add(0, e);
	}

	@Override
	public void addLast(E e) {
		add(size, e);
	}

	@Override
	public E get(int index) {
		if(index<0 || index>=size) {
			throw new IllegalArgumentException("查询下标非法");
		}
		Node p = head;
		for(int i=0;i<index;i++) {
			p = p.next;
		}
		return p.data;
	}

	@Override
	public E getFirst() {
		return get(0);
	}

	@Override
	public E getLast() {
		return get(size-1);
	}

	@Override
	public void set(int index, E e) {
		if(index<0 || index>=size) {
			throw new IllegalArgumentException("修改下标非法");
		}
		Node p = head;
		for(int i=0;i<index;i++) {
			p = p.next;
		}
		p.data = e;
	}

	@Override
	public boolean contains(E e) {
		return find(e)!=-1;
	}

	@Override
	public int find(E e) {
		if(isEmpty()) {
			return -1;
		} else {
			Node p = head;
			for(int i=0;i<getSize();i++) {
				if(p.data==e) {
					return i;
				}
				p = p.next;
			}
		}
		return -1;
	}

	@Override
	public E remove(int index) {
		if(index<0 || index>=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<index-1;i++) {
				p = p.next;
			}
			n = p.next;
			e = p.next.data;
			p.next = n.next;
			n.next = null;
		}
		size--;
		return e;
	}

	@Override
	public E removeFirst() {
		return remove(0);
	}

	@Override
	public E removeLast() {
		return remove(size-1);
	}

	@Override
	public E removeElement(E e) {
		int i = find(e);
		if(i==-1) {
			throw new IllegalArgumentException("删除元素不存在");
		}
		return remove(i);
	}

	@Override
	public void clear() {
		head = null;
		rear = null;
		size =0;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("LoopSingle: size="+size+"\n");
		if(size==0) {
			sb.append("[]");
		} else {
			sb.append('[');
			Node p = head;
			while(p!=rear) {
				sb.append(p.data+",");
				p = p.next;
			}
			sb.append(rear.data+"]");
		}
		return sb.toString();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean equals(Object obj) {
		if(obj == null) {
			return false;
		} 
		if(obj == this) {
			return true;
		}
		if(obj instanceof LoopSingle) {
			LoopSingle<E> loop = (LoopSingle<E>) obj;
			if(getSize()==loop.getSize()) {
				Node n = head;
				Node p = loop.head;
				for(int i=0;i<getSize();i++) {
					if(n.data!=p.data) {
						return false;
					}
					n = n.next;
					p = p.next;
				}
				return true;
			}
			
		}
		return false;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值