首先我说下我自己对链表的理解

链表它就相当于一个火车 ,火车有很多节车厢(车厢就相当于链表中的节点);

一个车厢包括  车厢里面的人或者东西 还有和下一节车厢相连的挂钩

那么这就很形象的说明了  链表的每个节点  包括  data  和 next  (数据和指向下一个节点的指针)

单链表图示:

 

单链表的实现

单链表的实现:

/*
 * 线性表的接口的定义
 */
public interface MyList {
	/*
	 * 增加元素
	 */
	void add(Object element);
	
	/*
	 * 删除元素
	 */
	void delete(Object element);
	//删除指定索引的元素
	void delete(int index);
	
	/*
	 * 更新元素
	 * 修改指定索引的值为新的element
	 */
	void update(int index,Object NewElement);
	
	/*
	 * 查询元素
	 */
	boolean contains(Object target);

	//查找element元素的索引   如果没有返回-1
	int indexOf(Object element);
	
	//返回指定索引的元素
	Object at(int index);
}
public class ListNode {
	 Object data;
	 ListNode next;
	
	public ListNode(Object data){
		this.data = data;
	}
}
/*
 * 单链表的实现
 */
public class SingleLinkedList implements MyList {
	private ListNode first;	//头节点
	private ListNode last;	//最后的节点
	private int size;
	
	//向链表中添加一个节点
	@Override
	public void add(Object element) {
		//先判断链表是否为空
		if(first == null)
		{
			first = new ListNode(element);
			last = first;
		}
		else{
			//头节点不为空的话
			last.next = new ListNode(element);
			last = last.next;
		}
		size++;
	}
	
	//删除节点
	@Override
	public void delete(Object element) {
		ListNode p = first;
		ListNode pre = null; //记录当前访问节点的前一个节点  
		//遍历链表
		while(p!=null)
		{
			if(p.data.equals(element))
			{
				//需要判断p是不是头节点
				if(p == first)
				{
					//直接将头节点指向下一个结点  就相当于删除了头节点
					first = first.next;
				}
				else
				{
				//如果当前节点不是头节点并且是要删除的结点的话
				pre.next = p.next;
				}
				break;
			}
			//如果当前节点不是要删除的结点的话  那么需要记录当前节点
			pre= p;
			//然后继续向后遍历
			p = p.next;
		}
		size--;
	}
	
	//通过给定的索引值去删除节点 
	//需要考虑的一个问题就是  一直删的话  会不会出现越界问题
	@Override
	public void delete(int index) {
		//先判断索引值 是否在范围内 如果不在话 直接return
		if(index<0||index>=size)
		{
			return;
		}
		ListNode p = first;
		ListNode pre = null;
		int i = 0;			//和每个结点相对应
		
		while(p != null)
		{
			if(i == index)
			{
				if(p == first)
				{
					first = first.next;
				}
				else{
					pre.next = p.next;
				}
				break;
			}
			i++;
			pre = p;
			p = p.next;
		}
		size--;
	}

	@Override
	public void update(int index, Object NewElement) {
		//先判断索引值 是否在范围内 如果不在话 直接return
				if(index<0||index>=size)
				{
					return;
				}
		
		ListNode p = first;
		int i = 0;			//和每个结点相对应
		
		while(p != null)
		{
			if(i == index)
			{
				p.data = NewElement;
				break;
			}
			i++;
			p = p.next;
		}
	}

	@Override
	public boolean contains(Object target) {
		ListNode p = first;
		while(p != null)
		{
			if(p.data.equals(target))
			{
				return true;
			}
			p = p.next;
		}
		return false;
	}

	@Override
	public int indexOf(Object element) {
		ListNode p = first;
		int i = 0;
		while(p!=null)
		{
			if(p.data.equals(element))
			{
				return i;
			}
			i++;
			p = p.next;
		}
		return -1;
	}
	
	@Override
	public Object at(int index) {
		if(index<0||index>=size)
		{
			return null;
		}
		int i = 0;
		ListNode p = first;
		
		while(p!=null)
		{
			if(i == index)
			{
				return p.data;
			}
			i++;
			p = p.next;
		}
		return null;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		//遍历 首先需要将头节点先复制一下  不能直接将头节点拿过来使用
		ListNode p = first;
		
		while(p!=null)
		{
			sb.append(p.data);
			p = p.next;
			if(p!=null)
			{
				sb.append(",");
			}
		}
		sb.append("]");
		return sb.toString();
	}
}

测试:

public class Test {
	public static void main(String[] args) {
		
		SingleLinkedList list = new SingleLinkedList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		list.add("e");
		System.out.println(list.toString());
		list.delete("c");
		System.out.println(list.toString());
		list.delete(2);
		System.out.println(list.toString());
		list.update(0, "w");
		System.out.println(list.toString());
		System.out.println(list.contains("b"));
		System.out.println(list.contains("j"));
		System.out.println(list.at(0));
		System.out.println(list.indexOf("b"));
		System.out.println(list.indexOf("j"));
		
	}
}

 

相关文章: