链表结束——单链表的插入和删除

链表结束——单链表的插入和删除

链表的插入:
1.我们把链表的插入分为三种情况头插,尾插和中间插
2.我们定义两个指针head和rear
3.刚开始当链表的size=0时我们head=rear指向一个无意义的节点作为表头
4.插入时我们按照索引进行插入:
分为三种情况:
1.当index=0时我们进行头插
头插时我们的逻辑很简单我们让要插入的节点node.next=head.next,head.next=node就可以了
这里当size=0时
我们插入一个节点rear要后移
rear=head.next;
2.当index==size时我们尾插
尾插很简单两步走我们直接让rear.next=node,rear=node;
3.当index不为负数的其他情况进行中间插入
最后一种情况中间插入首先我们需要找到要插入节点的前驱(使用for循环循环index-1下就可以找到前驱)我们把前驱给一个变量node1
接下来我们开始插入node.next=node1.next,node1.next=node,
之后无论任何插入size++,
上代码:

public void add(int index, E e) {
		Node n=new Node(e);
	   //链表一般来说是不会满的
		if(index==0){
			//头插法
			n.next=head.next;
			head.next=n;
			if(size==0){
			  rear=n;
			}
			
		}else if(index==size-1){
			//尾插法
			rear.next=n;
			rear=n;
		}else{
			Node p=find(index);
			n.next=p.next;//把原来位置上的节点拼到下一个
			p.next=n;//把n拼到此位置
		}
		size++;
		
	}
	//辅助函数寻找前驱这里从head开始有个空节点所以循环index次
	public Node find(int index){
	  Node p=head;//从角标0开始遍历
	  for(int i=0;i<index;i++){
		  p=p.next;
	  }
	  return p;
  }

链表的删除分为两种
1.按值删
删除呢就非常的简单我们只需要找到要删除节点的val的前驱然后p.next=p.next.next,就行了如果没找到则链表不动(了解一下没有考虑size==1时删除rear的移动)
上代码:

@Override
	public void removeElement(E e) {
	    Node p=head.next;
		while(true){
			if(p.next.data.equals(e)){
			    p.next=p.next.next;
				break;
			}
			p=p.next;
		}
	}

2.按索引删
这种删除和插入一样分为头删,尾删和中间删
1.头删
当index=0时
head.next=head.next.next;
当size==1时删除
rear=head;
2.尾删
当indxe=size-1时
我们找到删除节点的前驱node
node.next=null;
rear=node;
3.中间删
同样先找到前驱node然后node.next=node.next.next
三种情况都是删别忘了size–
上代码

public E remove(int index) {
		if(isEmpty()){
			throw new IllegalArgumentException("链表为空");
		}
		E res=null;
		if(index==0){
	    res=head.next.data;
	    head.next=head.next.next;
	    if(size==1){
	    	rear=head;
	    }
		}else if(index==size-1){
			Node p=find(index);
			res=p.next.data;
			p.next=null;
			rear=p;
		}else{
			Node p=find(index);
			res=p.next.data;
			p.next=p.next.next;
		}
		size--;
		return res;
	}

然后
最后为了大家能够有更深刻的理解奉上linkist的实现及其测试类

public class LinkedList<E> implements List<E>{
	private Node head;//头指针
	private Node rear;//尾指针
	private int size;
	//链表节点
    class Node{
    	E data;
    	Node next;
    	public Node(){
    		this(null,null);
    	}
    	public Node(E data){
    		this(data,null);
    	}
		public Node(E data, Node next) {
			this.data = data;
			this.next = next;
		}
    	
    }
    
	public LinkedList() {
		this.head = new Node();
		this.rear =this.head;
		this.size =0;
	}

	@Override
	public int getSize() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return head.next==null;
	}

	@Override
	public void add(int index, E e) {
		Node n=new Node(e);
	   //链表一般来说是不会满的
		if(index==0){
			//头插法
			n.next=head.next;
			head.next=n;
			if(size==0){
			  rear=n;
			}
			
		}else if(index==size-1){
			//尾插法
			rear.next=n;
			rear=n;
		}else{
			Node p=find(index);
			n.next=p.next;//把原来位置上的节点拼到下一个
			p.next=n;//把n拼到此位置
		}
		size++;
	}

	@Override
	public void addFirst(E e) {
	   add(0, e);
	}

	@Override
	public void addLast(E e) {
		add(size-1, e);
	}

	@Override
	public void set(int index, E e) {
		if(isEmpty()){
			throw new IllegalArgumentException("链表为空");
		}
		Node p=find(index+1);
		p.data=e;
	}

	@Override
	public E get(int index) {
		return find(index+1).data;
	}
	@Override
	public E getFirst() {
		return get(0);
	}

	@Override
	public E getLast() {
		return get(size-1);
	}

	@Override
	public boolean contains(E e) {
		if(find(e)!=-1){
			return true;
		}
		return false;
	}

	@Override
	public int find(E e) {
	    Node p=head.next;
	    int index=-1;
	    while(!p.data.equals(e)){
	    	index++;
	    	p=p.next;
	    	if(index==size-1){
	    		index=-1;
	    		break;
	    	}
	    }
		return index;
	}

	@Override
	public E remove(int index) {
		if(isEmpty()){
			throw new IllegalArgumentException("链表为空");
		}
		E res=null;
		if(index==0){
	    res=head.next.data;
	    head.next=head.next.next;
	    if(size==1){
	    	rear=head;
	    }
		}else if(index==size-1){
			Node p=find(index);
			res=p.next.data;
			p.next=null;
			rear=p;
		}else{
			Node p=find(index);
			res=p.next.data;
			p.next=p.next.next;
		}
		size--;
		return res;
	}

	@Override
	public E removeFirst() {
		return remove(0);
	}

	@Override
	public E removeLast() {
		return remove(size-1);
	}

	@Override
	public void removeElement(E e) {
	    Node p=head.next;
		while(true){
			if(p.next.data.equals(e)){
			    p.next=p.next.next;
				break;
			}
			p=p.next;
		}
	}

	@Override
	public void clear() {
	    head.next=null;
		rear=head;
		size=0;
	}
  public Node find(int index){
	  Node p=head;//从角标0开始遍历
	  for(int i=0;i<index;i++){
		  p=p.next;
	  }
	  return p;
  }
  public String toString(){
	  Node p=head.next;
	  StringBuilder sb=new StringBuilder();
	  for(int i=0;i<size;i++){
		  sb.append(p.data);
		  p=p.next;
	  }
	  return sb.toString();
  }
}

测试类

import com.lipengge.list.LinkedList;

public class TestLinkList {
   public static void main(String[] args) {
	LinkedList<Integer> ls=new LinkedList<Integer>();
	System.out.println(ls);
	ls.add(0, 1);
	ls.add(0, 2);
	ls.add(0, 3);
	ls.add(0, 4);
	ls.add(0, 5);
	ls.add(0, 6);
	System.out.println(ls);
	//System.out.println(ls.getSize()-1);
	//System.out.println(ls.getLast());
	ls.add(ls.getSize()-1, 1);
	System.out.println(ls.getLast());
	ls.add(ls.getSize()-1, 2);
	ls.add(ls.getSize()-1, 3);
	ls.add(ls.getSize()-1, 4);
	ls.add(ls.getSize()-1, 5);
	ls.add(ls.getSize()-1, 6);
	System.out.println(ls.getLast());
	System.out.println(ls);
	System.out.println(ls.removeLast());
	System.out.println(ls);
	System.out.println(ls.removeFirst());
	System.out.println(ls);
	System.out.println(ls.remove(3));
	System.out.println(ls);
	ls.set(ls.getSize()-1, 10);
	System.out.println(ls);
	System.out.println(ls.contains(18));
	System.out.println(ls.get(3));
	ls.clear();
	System.out.println("...."+ls);
	System.out.println("...."+ls.getSize());
	
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值