自己实现双向循环链表和单向循环链表

这次的两循环链表是基于上篇的两链表,不同的就是首尾相互指向,所以主要改动在add,remove方法上。

单向循环链表

package com.ldg.circle;

import java.util.IllegalFormatCodePointException;

import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID;

import com.ldg.AbstractList;



@SuppressWarnings("unused")
//单向循环链表类
//相对与单链表只需要修改add remove部分  其他的通用
public class SingleCircleLinkedList<T> extends AbstractList<T> {
	// 指的是首节点 由首节点指向链表
	private Node<T> first;

	// 声明节点类
	@SuppressWarnings("hiding")
	private class Node<T> {

		T element;
		Node<T> next;

		public Node(T element, Node<T> next) {

			this.element = element;
			this.next = next;
		}

	}

	/**
	 * 根据序号返回节点 从首节点一个个next
	 * 
	 * @param index
	 * @return
	 */
	public Node<T> node(int index) {
		// 判断序号是否越界
		isOutSize(index);
		Node<T> node = first;
		for (int i = 0; i < index; i++) {
			node = node.next;
		}

		return node;
	}

	/**
	 * 根据索引添加元素 返回原始值 注意index=0 index=size index=size-1的边界情况
	 * 
	 */
	@Override
	public T add(int index, T element) {

		T old;
		// 改成循环链表时修改if这部分,else可以继续使用.
		//是不是index=0 添加
		if (index == 0) {
			//声明新节点
			Node<T> node = new Node<T>(element, first);
			//判断:新节点是不是第一个节点
			if (first == null) 
			{
				old = null;
				first = node;
				node.next = first;

			} else {
				old = first.element;
				node(size - 1).next = node;
				first = node;

			}

		} else {

			Node<T> node = node(index - 1).next;
			if (node == null) {
				old = null;
			} else {
				old = node.element;
			}
            
			node(index - 1).next = new Node<T>(element, node(index - 1).next);

		}
		size++;
		return old;
	}

	@Override
	public void add(T element) {
		add(size, element);
	}

	@Override
	public T remove(int index) {
		isOutSize(index);
		T old;
		//删除第一节点
		if (index == 0) 
		{

			old = first.element;
			if (size == 1) {
				first = null;
			} else {
				//最后一个节点指向第一个节点
				node(size - 1).next = first.next;
				//first指向第一个节点
				first = first.next;
			}

		} else {
			old = node(index).element;
			node(index - 1).next = node(index - 1).next.next;
		}
		size--;
		return old;
	}

	@Override
	public T set(int index, T element) {

		T old = node(index).element;
		node(index).element = element;
		return old;
	}

	@Override
	public void clear() {
		size = 0;
		first = null;

	}

	@Override
	public T get(int index) {

		return node(index).element;
	}

	@Override
	public int indexOf(T element) {
		Node<T> node = first;
		for (int i = 0; i < size; i++) {
			if (node.element.equals(element)) {

				return i;
			}
			node = node.next;
		}
		return ELEMENT_NOT_FOUND;
	}

	@Override
	public String toString() {

		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("Size:" + size + " LinkedList[");
		for (int i = 0; i < size; i++) {
			if (i != 0) {
				stringBuilder.append(",");
			}
			stringBuilder.append(node(i).element);
		}
		stringBuilder.append("]");
		return stringBuilder.toString();
	}

	/***
	 * 反转链表
	 * 
	 * @param head
	 * @return
	 */
//	public Node<T> reverseList(Node<T> head) {
//
//		if (head == null || head.next == null)
//			return head;
//		// 与当前链表关联 这样才不会出现空指针
//		first = reverseList(head.next);
//		head.next.next = head;
//		head.next = null;
//
//		return first;
//
//	}
	// 判断是否为循坏链表
	public boolean hasCycle(Node<T> head) {
		if (head == null)
			return false;
		Node<T> slowListNode = head;
		Node<T> fastListNode = head.next;
		while (fastListNode != null && fastListNode.next != null) {
			slowListNode = slowListNode.next;
			fastListNode = fastListNode.next.next;
			if (slowListNode == fastListNode) {
				return true;
			}
		}
		return false;
	}

}

双向循环链表

package com.ldg.circle;

import java.util.IllegalFormatCodePointException;

import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID;

import com.ldg.AbstractList;

@SuppressWarnings("unused")
//双向循环链表类
//相对于双向链表修改的地方还是 add 和  remove
public class CircleLinkedList<T> extends AbstractList<T> {
	// 指的是首节点 由首节点指向链表
	private Node<T> first;
	// 尾节点
	private Node<T> last;

	// 声明节点类
	@SuppressWarnings("hiding")
	private class Node<T> {

		T element;
		// 后一个节点
		Node<T> next;
		// 前一个节点
		Node<T> pre;

		public Node(Node<T> pre, T element, Node<T> next) {
			this.pre = pre;
			this.element = element;
			this.next = next;
		}

	}

	/**
	 * 根据序号返回节点 分情况从头或者尾开始移动
	 * 
	 * @param index
	 * @return
	 */
	public Node<T> node(int index) {
		// 判断序号是否越界
		isOutSize(index);
		Node<T> node = null;
		if (index < size >> 2) {
			node = first;
			for (int i = 0; i < index; i++) {
				node = node.next;
			}

		} else {
			node = last;
			for (int i = size - 1; i > index; i--) {
				node = node.pre;
			}
		}
		return node;
	}

	/**
	 * 注意一下节点中两个指针的指向.不要漏忘 根据索引添加元素 返回原始值 
	 * 注意index=0 index=size index=size-1的边界情况
	 */
	@Override
	public T add(int index, T element) {

		T old;
		// 直接添加到链表最后面
		if (index == size) {
			old = null;
			Node<T> pre = last;
			Node<T> node = new Node<T>(pre, element, first);
			last = node;
			if (index == 0) // 当index=size=0;唯一的一个节点
			{   //自己指向自己
				first = node;
				node.next=node;
				node.pre=node;
			} else {
                //首尾相指
				first.pre = node;
				pre.next = node;
			}

		} else {

			Node<T> next = node(index);
			old = next.element;
			Node<T> pre = node(index).pre;
			Node<T> node = new Node<T>(pre, element, next);
			if (index == 0)// index=0
			{
				first = node;
			} else {
				pre.next = node;
			}
			next.pre = node;
		}
		size++;
		return old;
	}

	/**
	 * 添加
	 */
	@Override
	public void add(T element) {
		add(size, element);
	}

	/**
	 * 移除节点
	 * 条件判断具有对称性。
	 */
	@Override
	public T remove(int index) {
		isOutSize(index);
		T old = null;
		Node<T> next = node(index).next;
		Node<T> pre = node(index).pre;
		if (index == 0) // index=0的情况
		{

			first = next;
			last.next=first;

		} else {

			pre.next = next;
		}
		if (index == size - 1) // index=size-1的情况;
		{   
			
			last = pre;
			first.pre=last;

		} else {
			next.pre = pre;
		}

		size--;
		return old;
	}

	@Override
	public T set(int index, T element) {

		T old = node(index).element;
		node(index).element = element;
		return old;
	}

	// 如果不是被gc root对象指向的内存地址块会被java回收站机制回收。
	// 就是没局部变量指向的对象。
	@Override
	public void clear() {

		size = 0;
		first = null;
		last = null;

	}

	@Override
	public T get(int index) {

		return node(index).element;
	}

	@Override
	public int indexOf(T element) {
		Node<T> node = first;
		for (int i = 0; i < size; i++) {
			if (node.element.equals(element)) {

				return i;
			}
			node = node.next;
		}
		
		return ELEMENT_NOT_FOUND;
	}

	// Stringbuilder的拼接
	@Override
	public String toString() {

		StringBuilder stringBuilder = new StringBuilder();

		stringBuilder.append("Size:" + size + " LinkedList[");
		for (int i = 0; i < size; i++) {
			if (i != 0) {
				stringBuilder.append(",");
			}
			

			stringBuilder.append(node(i).element);
		}
		stringBuilder.append("]");
		
		return stringBuilder.toString();
	}

	/***
	 * 反转链表
	 * 
	 * @param head
	 * @return
	 */
//	public Node<T> reverseList(Node<T> head) {
//
//		if (head == null || head.next == null)
//			return head;
//		// 与当前链表关联 这样才不会出现空指针
//		first = reverseList(head.next);
//		head.next.next = head;
//		head.pre = head.next;
//		last = head;
//
//		return first;
//
//	}

	// 判断是否为循坏链表
	public boolean hasCycle(Node<T> head) {
		if (head == null)
			return false;
		Node<T> slowListNode = head;
		Node<T> fastListNode = head.next;
		while (fastListNode != null && fastListNode.next != null) {
			slowListNode = slowListNode.next;
			fastListNode = fastListNode.next.next;
			if (slowListNode == fastListNode) {
				return true;
			}
		}
		return false;
	}

}

外加一个检测是否为循环链表的小算法


	// 判断是否为循坏链表
	public boolean hasCycle(Node<T> head) {
		if (head == null)
			return false;
		Node<T> slowListNode = head;
		Node<T> fastListNode = head.next;
		while (fastListNode != null && fastListNode.next != null) {
			slowListNode = slowListNode.next;
			fastListNode = fastListNode.next.next;
			if (slowListNode == fastListNode) {
				return true;
			}
		}
		return false;
	}

以上代码经测试都能够跑通。

发布了23 篇原创文章 · 获赞 17 · 访问量 1289

猜你喜欢

转载自blog.csdn.net/qq_41587409/article/details/105046272
今日推荐