java 链表的实现

public class SingleLinkedList<T> {
	
	/*
	 * 节点类
	 * */
	public static class Node<T>{
		T nodeValue;
		Node<T> next;//指向下一个节点的引用
		Node(T nodeValue, Node<T> next){
			this.nodeValue = nodeValue;
			this.next = next;
		}
		Node(T nodeValue){
			this(nodeValue, null);
		}
	}
	//下面是SingleLinkedList类的数据成员和方法
	public Node<T> head, tail;
	public SingleLinkedList(){
		head = tail = null;
	}
	/*
	 * 判断链表是否为空
	 * */
	public boolean isEmpty(){
		return head == null;
	}
	/*
	 *创建头指针,该方法只用一次 
	 * */
	public void addToHead(T item){
		head = new Node<T>(item);
		if(tail == null) tail = head;
		tail.next = null;
	}
	/*
	 *添加尾指针,该方法使用多次 
	 * */
	public void addToTail(T item){
		if(!isEmpty()){//若链表非空那么将尾指针的next初始化为一个新的元素
			tail.next = new Node<T>(item);
			tail = tail.next;
			tail.next = null;
		}
		else{
			head = tail = new Node<T>(item);
			tail.next = null;
		}
	}
	/*
	 * 打印列表
	 * */
	public void printList(){
		if(isEmpty()){
			System.out.println("null");
		}else{
			for(Node<T> p = head; p != null; p = p.next){
				System.out.print(p.nodeValue + " ");
			}
		}
	}
	/*
	 * 在表头插入结点,效率非常高
	 * */
	public void  addFirst(T item){
		Node<T> newNode = new Node<T>(item);
		newNode.next = head;
		head = newNode;
	}
	/*
	 * 在表尾插入结点,效率很低
	 * */
	public void addLast(T item){
		Node<T> newNode = new Node<T>(item);
		Node<T> p = head;
		while(p.next != null) p = p.next;
		p.next = newNode;
		newNode.next = null;
	}
	/*
	 * 在表头删除结点,效率非常高
	 * */
	public void removeFirst(){
		if(!isEmpty()) head = head.next;
		else System.out.println("The list have been emptied");
	}
	/*
	 * 在表尾删除结点,效率很低
	 * */
	public void removeLast(){
		Node<T> prev = null, curr = head;
		while(curr.next != null){
			prev = curr;
			curr = curr.next;
			if(curr.next == null) prev.next = null;
		}
	}
	/*
	 * <p>插入一个新结点</p>   
     * <ul>插入操作可能有四种情况:   
     * <li>①表为空, 返回false</li>   
     *<li>②表非空,指定的数据不存在</li>   
     * <li>③指定的数据是表的第一个元素</li>   
     * <li>④指定的数据在表的中间</li></ul>   
     * @param appointedItem 指定的nodeValue   
     * @param item 要插入的结点   
     * @return 成功插入返回true;
	 * */
	public boolean insert(T appointedItem, T item){
		Node<T> prev = head, curr = head.next, newNode;
		newNode = new Node<T>(item);
		if(!isEmpty()){
			while((curr != null) && (!appointedItem.equals(curr.nodeValue))){
				//两个判断条件不能换
				prev = curr;
				curr = curr.next;
			}
			newNode.next = curr;
			prev.next = newNode;
			return true;
		}
		return false;
	}
     /*  
      * <p>移除此列表中首次出现的指定元素</p>   
	  * <ul>删除操作可能出现的情况:   
	  * <li>①prev为空,这意味着curr为head. head = curr.next; --> removeFirst();</li>   
	  * <li>②匹配出现在列表中的某个中间位置,此时执行的操作是 --> prev.next = curr.next;,</li></ul>   
	  * <p>在列表中定位某个结点需要两个引用:一个对前一结点(prev左)的引用以及一个对当前结点(curr右)的引用.</p>   
	  * prev = curr;   
	  * curr = curr.next;   
	  */  
	public void remove(T item){
		Node<T> curr = head, prev = null;
		boolean found = false;
		while(curr != null && !found){
			if(item.equals(curr.nodeValue)){
				if(prev == null)
					removeFirst();
				else
					prev.next = curr.next;
				found = true;
			}else{
				prev = curr;
				curr = curr.next;
			}
		}
	}
	/*
	 * 返回此列表中首次出现的指定元素的索引,如果列表中不包含此元素,则返回-1
	 *
	 * */
    public int indexOf(T item){
    	int index = 0;
    	Node<T> p;
    	for(p = head; p != null; p = p.next){
    		if(item.equals(p.nodeValue))
    			return index;
    		++index;
    	}
    	return -1;
    }
    /*
     * 如果此列表包含指定元素,则返回true
     * */
    public boolean contains(T item){
    	return indexOf(item) != -1;
    }
    public static void main(String[] args){
    	SingleLinkedList<String> t = new SingleLinkedList<String>();
    	t.addToHead("A");
    	t.addFirst("addFirst");
    	t.addToTail("B");
    	t.addToTail("C");
    	System.out.println(t.indexOf("C"));
    	System.out.println(t.contains("A"));
    	t.addLast("addLast");
    	t.removeLast();
    	t.insert("B", "insert");
    	t.removeFirst();
    	t.remove("B");
    	t.printList();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值