自定义链表(1)

通过学习自定义链表,了解链表的数据结构。

首先写一个链表类  :LinkedList.java

最后,测试: Test.java、

 

知识点

1.链表的内部维护了一个节点Node类。该类包括数据域和指针域(指针域指向下一个Node节点)

2.通常需要一个虚拟头结点,但不是必须的。

 

 

结构:

LinkedList.java:

package LinkedList;

public class LinkedList <E>{
	/**
	 * 维护的一个内部类,描述节点信息
	 * @author Xiaohua
	 *
	 */
	private class Node{
		public E e;//数据域
		public Node next;//指针域
		
		public Node(E e, Node next) {
			this.e=e;
			this.next=next;
			
		}
		public Node(E e) {
			this(e,null);
		}
		
		public Node() {
			this(null,null);
		}
		@Override
		public String toString() {
			
			return e.toString();
		}
		
	}
	
	private Node dummyHead;//虚拟头结点
	private int size;//链表大小
	/**
	 * 无参构造函数,初始化一个虚拟头结点,数据域、指针域都为null。
	 */
	public LinkedList() {
		dummyHead=new Node();
		size=0;
	}
	/**
	 * 获取链表中元素个数
	 * @return
	 */
	public int getSize() {
		return size;
	}
	/**
	 * 判断链表是否为空
	 * @return
	 */
	public boolean isEmpty() {
		return size==0;
	}
	
	/**
	 * 在链表的指定位置添加元素
	 * (不是常用操作,练习用)
	 * pre的作用:找到要插入索引位置的前一个Node节点
	 * @param index
	 * @param e
	 */
	public void add(int index,E e) {
		if(index < 0 || index > size) {
            throw new IllegalArgumentException("添加失败,不合法的索引值");
		}
		Node pre=dummyHead;
		for(int i=0;i<index;i++) {
			pre=pre.next;
		}
		Node node=new Node(e);
		node.next=pre.next;
		pre.next=node;
		//以上3句等价于这1句:
		//pre.next = new Node(e, pre.next);
		size++;
	}
	/**
	 * 在链表头部添加元素
	 * @param e
	 */
	public void addFirst(E e) {
		add(0,e);
	}
	/**
	 * 在链表尾部添加元素
	 * @param e
	 */
	public void addLast(E e) {
		add(size,e);
	}
	/**
	 * 获取链表指定索引的元素
	 * (不是常用操作,练习用)
	 * cur的作用:代表当前指向的Node节点。
	 * @param index
	 * @return
	 */
	public E get(int index) {
		if(index < 0 || index >= size) {
            throw new IllegalArgumentException("获取失败,不合格索引。");
		}
		
		Node cur=dummyHead.next;
		for(int i=0;i<index;i++) {
			cur=cur.next;
		}
		return cur.e;
	}
	/**
	 * 获得链表的第一个元素
	 * @return
	 */
	public E getFirst() {
		return get(0);
	}
	/**
	 * 获得链表的最后一个元素
	 * @return
	 */
	public E getLast() {
		return get(size-1);
	}
	/**
	 * 修改链表的指定索引的值。
	 * (不是常用操作,练习用)
	 * @param index
	 * @param e
	 */
	public void set(int index,E e) {
		if(index < 0 || index >= size) {
            throw new IllegalArgumentException("设置失败,不合法索引.");
		}
		Node cur=dummyHead.next;
		for(int i=0;i<index;i++) {
			cur=cur.next;
			
		}
		cur.e=e;
		
	}
	
	/**
	 * 判断链表中是否含有指定元素。
	 * @param e
	 * @return
	 */
	public boolean contains(E e) {
		Node cur=dummyHead.next;
		while(cur!=null) {
			if(cur.e.equals(e)) {
				return true;
			}
			cur=cur.next;
		}
		return false;
	}
	/**
	 * 删除指定索引位置的元素,并返回。
	 * (不是常用操作,练习用)
	 * @param index
	 * @return
	 */
	public E remove(int index) {
		if(index < 0 || index >= size) {
            throw new IllegalArgumentException("删除失败,不合法索引.");
		}
		Node pre=dummyHead;
		for(int i=0;i<index;i++) {
			pre=pre.next;
			
		}
		Node ret=pre.next;
		pre.next=ret.next;
		ret.next=null;
		size--;
		return ret.e;
		
	}
	/**
	 *  从链表中删除第一个元素, 返回删除的元素
	 * @return
	 */
    public E removeFirst(){
        return remove(0);
    }

    /**
     *  从链表中删除最后一个元素, 返回删除的元素
     * @return
     */
    public E removeLast(){
        return remove(size - 1);
    }
    /**
     * 从链表删除指定元素
     * @param e
     */
	public void removeElement(E e) {
		Node pre=dummyHead;
		while(pre.next!=null) {
			if(pre.next.e.equals(e)) {
				break;
			}
			pre=pre.next;
		}
		
		if(pre.next!=null) {
			Node delNode=pre.next;
			pre.next=delNode.next;
			delNode.next=null;
			size--;
		}
	}
	/**
	 * 重写Object的toString方法
	 */
	public String toString() {
		StringBuilder sb=new StringBuilder();
		Node cur=dummyHead.next;
		while(cur!=null) {
			sb.append(cur+"-->");
			cur=cur.next;
		}
		sb.append("null");
		return sb.toString();
	}
	
	
	

	
	
}

Test.java:

package LinkedList;

public class Test {
	public static void main(String[] args) {

        LinkedList<Integer> linkedList = new LinkedList<>();
        for(int i = 0 ; i < 5 ; i ++){
            linkedList.addFirst(i);
            System.out.println(linkedList);
        }

        linkedList.add(2, 666);
        System.out.println(linkedList);
        
        linkedList.remove(2);
        System.out.println(linkedList);

        linkedList.removeFirst();
        System.out.println(linkedList);

        linkedList.removeLast();
        System.out.println(linkedList);
    }
}

控制台输出结果;

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值