简单实现LinkedList

LinkedList本质上是链表,此次只是实现了LinkedList里面几个基础简单的方法,为了便于理解LinkedList

节点类

节点类里面包括指向上一个节点的指针,指向下一个节点的指针,和保存数据的Object类,以及两个构造方法。

/**
 * 节点类
 * TODO
 * @version 1.0
 * @author 王星宇
 */
class Node{
	Node previous;  //上一个节点
	Node next;   //下一个节点
	Object element;   //数据
	
	public Node(Node previouse,Node next,Object element) {
		this.previous = previouse;
		this.next = next;
		this.element = element;
	}
	
	public Node(Object element) {
		this.element = element;
	}
}

需要的变量

  • 头指针first
  • 尾指针last
  • 容器大小size;
	private Node first;
	private Node last;
	
	private int size;

checkIndex()

检查索引是否合法,如果不合法,则抛出异常

/**
	 * 检查索引是否合法
	 * @param index
	 */
	public void checkIndex(int index) {
		if(index < 0||index >= size)
			throw new RuntimeException("索引不合法:" + index);
	}

get()和getNode()

  • getNode(int index):获得索引处的节点,当索引小于长度的一半时,从前面开始查找,当索引大于长度的一半时,从后面开始查找。
  • get(int index):获得索引处节点的数据,检查索引是否合法,调用getNode()获得索引处的节点,返回节点的数据。
/**
	 * get方法
	 *   如果是前半部分,从前面开始找
	 *   如果是后半部分,从后面开始找
	 * @param index
	 * @return
	 */
	public E get(int index) {
		checkIndex(index);
		Node temp = getNode(index);
		return (E)temp.element;
	}
	/**
	 * 获得索引处的对象
	 * @param index
	 * @return
	 */
	public Node getNode(int index) {
		Node temp = null;
		if(index <= (size >> 1)) {
			temp = first;
			for(int i = 0;i < index;i++)
				temp = temp.next;
		}else {
			temp = last;
			for(int i = size - 1;i > index;i--)
				temp = temp.previous;
		}
		return temp;
	}

add()方法

  • add(E element):在容器最后添加一个对象,如果容器内没有对象,直接将头指针,尾指针都指向新建的节点,size++。
  • add(E element,int index):在指定索引处添加一个对象(如果容器内没有对象则抛出异常),调用getNode()获得索引处的节点,让down指向它,让up等于索引出前一个节点,之后让新节点的previous,next分别指向up和down,up.next,down.previous都指向新节点,最后size++;
/**
	 * 在链表最后里面添加一个对象
	 * @param obj 对象
	 */
	public void add(E element) {
		Node node = new Node(element);
		if(first == null) {
			first = node;
			last = node;
		}else {
			node.previous = last;
			node.next = null;
			last.next = node;
			last = node;
		}
		size++;
	}
	/**
	 * 在索引位置出添加节点
	 * @param obj 对象
	 * @param index  索引
	 */
	public void add(E element,int index) {
		checkIndex(index);
		Node newNode = new Node(element);
		Node down = getNode(index);
		Node up = down.previous;
		down.previous = newNode;
		newNode.next = down;
		if(up != null)
			up.next = newNode;
		else 
			first = newNode;
		size++;
	}

toString()

为了打印容器时能直接打印容器内的数据,重写toString()方法(System.out.println(myLinkedList); 实际上是调用的toString()方法)。

/**
	 * 返回链表中的数据
	 */
	@Override
	public String toString() {
		StringBuffer ms = new StringBuffer("");
		Node temp = first;
		ms.append("[");
		for(int i = 0;i < size;i++) {
			ms.append((temp.element).toString() + ",");
			temp = temp.next;
		}
		ms.setCharAt(ms.length() - 1, ']');
		return ms.toString();
	}

remove()

从容器中移除索引位置处的节点(对象本身并未删除)。首先检查索引是否合法,然后调用getNode()获得索引处的节点,up指向上一个节点,down指向下一个节点。

  • 如果up为null,则这个节点是头节点,移除的话直接将头指针指向dwon,down的previous等于null
  • 如果down为null,则这个节点是尾节点,移除的话直接将尾指针指向up,up的next等于null
  • 其他情况,up的下一个指向down,down的上一个指向up
  • size减一
/**
	 * 移除索引位置处的节点
	 * @param index
	 */
	public void remove(int index) {
		checkIndex(index);
		Node temp = getNode(index);
		if(temp != null) {
			Node up = temp.previous;
			Node down = temp.next;
			if(up == null) {
				first = down;
				down.previous = null;
			}else if(down == null) {
				last = up;
				up.next = null;
			}else {
				up.next = down;
				down.previous = up;
			}
			size--;
		}
	}

全部代码

package myCollection;

/**
 * 手写linkedList
 * TODO
 * @version 1.0
 * @author 王星宇
 */
public class myLinkedList <E>{
	private Node first;
	private Node last;
	
	private int size;
	/**
	 * 在链表最后里面添加一个对象
	 * @param obj 对象
	 */
	public void add(E element) {
		Node node = new Node(element);
		if(first == null) {
			first = node;
			last = node;
		}else {
			node.previous = last;
			node.next = null;
			last.next = node;
			last = node;
		}
		size++;
	}
	/**
	 * 返回链表中的数据
	 */
	@Override
	public String toString() {
		StringBuffer ms = new StringBuffer("");
		Node temp = first;
		ms.append("[");
		for(int i = 0;i < size;i++) {
			ms.append((temp.element).toString() + ",");
			temp = temp.next;
		}
		ms.setCharAt(ms.length() - 1, ']');
		return ms.toString();
	}
	/**
	 * get方法
	 *   如果是前半部分,从前面开始找
	 *   如果是后半部分,从后面开始找
	 * @param index
	 * @return
	 */
	public E get(int index) {
		checkIndex(index);
		Node temp = getNode(index);
		return (E)temp.element;
	}
	/**
	 * 获得索引处的对象
	 * @param index
	 * @return
	 */
	public Node getNode(int index) {
		Node temp = null;
		if(index <= (size >> 1)) {
			temp = first;
			for(int i = 0;i < index;i++)
				temp = temp.next;
		}else {
			temp = last;
			for(int i = size - 1;i > index;i--)
				temp = temp.previous;
		}
		return temp;
	}
	/**
	 * 检查索引是否合法
	 * @param index
	 */
	public void checkIndex(int index) {
		if(index < 0||index >= size)
			throw new RuntimeException("索引不合法:" + index);
	}
	/**
	 * 移除索引位置处的节点
	 * @param index
	 */
	public void remove(int index) {
		checkIndex(index);
		Node temp = getNode(index);
		if(temp != null) {
			Node up = temp.previous;
			Node down = temp.next;
			if(up == null) {
				first = down;
				down.previous = null;
			}else if(down == null) {
				last = up;
				up.next = null;
			}else {
				up.next = down;
				down.previous = up;
			}
			size--;
		}
	}
	/**
	 * 在索引位置出添加节点
	 * @param obj 对象
	 * @param index  索引
	 */
	public void add(E element,int index) {
		checkIndex(index);
		Node newNode = new Node(element);
		Node down = getNode(index);
		Node up = down.previous;
		down.previous = newNode;
		newNode.next = down;
		if(up != null)
			up.next = newNode;
		else 
			first = newNode;
		size++;
	}
}
/**
 * 节点类
 * TODO
 * @version 1.0
 * @author 王星宇
 */
class Node{
	Node previous;  //上一个节点
	Node next;   //下一个节点
	Object element;   //数据
	
	public Node(Node previouse,Node next,Object element) {
		this.previous = previouse;
		this.next = next;
		this.element = element;
	}
	
	public Node(Object element) {
		this.element = element;
	}
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值