Java数据结构---链表的基本用法(如创建等基本使用方法)

目录

一、单链表

(1)addFirst

(2)addLast

(3)遍历

(4)get

(5)insert

(6)removeFirst

(7)remove

二、双向链表

(1)insert

(2)remove

(3)addLast

(4) removeLast

三、双向环形链表

(1)添加

(2)删除首部和尾部

(3)删除或者寻找对应值的节点


一、单链表


//单向链表类
public class LinkedList {
    //头指针
    private Node head=null;
   private static class Node{
       int value;
       Node next;
       public Node(int value,Node next){
           this.value=value;
           this.next=next;
       }
   }

}

(1)addFirst

//头部添加元素
    public void addFirst(int value){
         head=new Node(value,head);
    }

(2)addLast

 //找到链表中的最后一个节点
    public Node findLast(){
       if(head==null){
           return null;
           //空链表
       }
       Node p;
       for(p=head;p.next!=null;p=p.next){
       }
       return p;
    }
    //向链表尾部添加元素
    public void addLast(int value){
       Node last=findLast();
       if(last==null){
           addFirst(value);
           return;
       }
       last.next=new Node(value,null);
    }

(3)遍历

//遍历链表
    public void loop(){
       Node p=head;
       while(p!=null){
           System.out.print(p.value+" ");
           p=p.next;
       }
       System.out.println();
    }

(4)get

获取指定索引的节点的value值。

这里注意一下findNode方法是获取指定索引处的节点,所以需要一个计量器i,让这个i=0开始,为什么呢?因为head其实就是第一个节点,后面双向链表计量i是=-1开始的,但是双向链表中的head并不是第一个节点,它的next才是第一个节点,所以一定要特别注意单向链表中的head与双向链表的head的区别(个人看法)

//找到指定索引处的节点
    public Node findNode(int index){

       int i=0;
       for(Node p=head;p.next!=null;p=p.next,i++){
           if(i==index){
               return p;
           }
       }
       return null;//没有找到该节点
    }
    //获取指定索引处的节点的值(value)
    public int get(int index){
       Node p=findNode(index);
       if(p==null){
           throw new IllegalArgumentException(String.format("index[%d]不合法",index));
       }
       return p.value;
    }

(5)insert

//向索引位置插入
    public void insert(int index,int value){
       if(index==0){
           addFirst(value);
       }
       //找到上一个节点
        Node prev=findNode(index-1);
       if(prev==null){
           throw new IllegalArgumentException(String.format("index[$d]不合法",index));
       }
       prev.next=new Node(value,prev.next);
    }

(6)removeFirst

//删除第一个节点
    public void removeFirst(){
       if(head==null){
           throw new IllegalArgumentException(String.format("index[0]不合法"));
       }
       head=head.next;
    }

(7)remove

  //删除指定索引处的节点
    public void remove(int index){
       if(index==0){
           removeFirst();
           return;
       }
       Node prev=findNode(index-1);//上一个节点
        if(prev==null){
            throw new IllegalArgumentException(String.format("索引异常"));
        }
        Node removed=prev.next;//被删除的节点
        if(removed==null){
            throw new IllegalArgumentException(String.format("索引异常"));
        }
        prev.next=removed.next;
    }

二、双向链表



//双向链表类
public class DoubleLinkedList {
     private Node head;
     private Node tail;

    private static class Node{
       Node prev;
       int value;
       Node next;
       public Node(Node prev,int value,Node next){
           this.prev=prev;
           this.value=value;
           this.next=next;
       }
    }
  //初始化
    public DoubleLinkedList(){
        head=new Node(null,100,null);
        tail=new Node(null,999,null);
        head.next=tail;
        tail.prev=head;
    }


}

(1)insert

在指定索引处添加

//找到指定索引处的节点
    private Node findNode(int index){
        int i=-1;
        for(Node p=head;p!=tail;i++,p=p.next){
            if(i==index){
                return p;
            }
        }
        return null;
    }
    //向指定位置添加节点
    public void insert(int index,int value){
        Node prev=findNode(index-1);
        if(prev==null){
            throw new IllegalArgumentException(String.format("索引异常"));
        }
        Node next=prev.next;
        Node inserted=new Node(prev,value,next);
        prev.next=inserted;
        next.prev=inserted;
    }

(2)remove

删除指定索引处的节点

//删除指定索引处的节点
    public void remove(int index){
        Node prev=findNode(index-1);
        if(prev==null){
            throw new IllegalArgumentException(String.format("索引异常"));
        }
        Node removed=prev.next;
        //如果删除的元素是尾哨兵
        if(removed==tail){
            throw new IllegalArgumentException(String.format("索引异常"));
        }
        Node next=removed.next;

        prev.next=next;
        next.prev=prev;
    }

(3)addLast

 向尾部添加节点

 //向尾部添加元素
   public void addLast(int value){
        Node last=tail.prev;
        Node added=new Node(last,value,tail);
        last.next=added;
        tail.prev=added;
   }

(4) removeLast

//删除最后一个节点
    public void removeLast(){
        Node removed=tail.prev;
        if(removed==head){
            throw new IllegalArgumentException(String.format("索引异常"));
        }
        Node prev=removed.prev;
        prev.next=tail;
        tail.prev=prev;
    }

三、双向环形链表

 双向环形链表(我这里说的是有哨兵节点的)不同的地方在于,尾结点的next指向了哨兵节点,哨兵节点的next指向的是第一个节点,哨兵节点的prev指向的是尾节点。

//双向环形链表
//注意是有哨兵节点sentinel
//sentinel.next是第一个节点,sentinel.prev是最后一个节点

public class DoubleSentinelList {

    private static class Node{
        Node prev;
        int value;
        Node next;

        public Node(Node prev, int value, Node next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    private Node sentinel=new Node(null,-1,null);//哨兵节点
    //初始化
    public DoubleSentinelList(){
        sentinel.next=sentinel;
        sentinel.prev=sentinel;
    }
}

(1)添加

//向首部添加
    public void addFirst(int value){
        Node a=sentinel;
        Node b=sentinel.next;
        Node added=new Node(a,value,b);
        a.next=added;
        b.prev=added;
    }
    //向尾部添加
    public void addLast(int value){
        Node a=sentinel.prev;
        Node b=sentinel;
        Node added=new Node(a,value,b);
        a.next=added;
        b.prev=added;
    }

(2)删除首部和尾部

 //删除首部
    public void removeFirst(){
        Node removed=sentinel.next;
        if(removed==sentinel){
            throw new IllegalArgumentException(String.format("非法"));
        }
        Node a=sentinel;
        Node b=removed.next;
        a.next=b;
        b.prev=a;
    }
    //删除尾部
    public void removeLast(){
        Node removed=sentinel.prev;
        if(removed==sentinel){
            throw new IllegalArgumentException(String.format("非法"));
        }
        Node a=removed.prev;
        Node b=sentinel;
        a.next=b;
        b.prev=a;
    }

(3)删除或者寻找对应值的节点

//根据值寻找对应的节点
    public Node findByValue(int value){
        Node p=sentinel.next;
        while(p!=sentinel){
            if(p.value==value){
                return p;
            }
            p=p.next;
        }
        return null;
    }
    //根据值删除对应的节点
    public void removeByValue(int value){
        Node removed=findByValue(value);
        if(removed==null){
            return;//不用删除,因为没找到
        }
        Node a=removed.prev;
        Node b=removed.next;
        a.next=b;
        b.prev=a;
    }

 

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
  链表类List的源代码如下: import Java.io.*; public class List {  /*用变量来实现表头*/  private Node Head=null;  private Node Tail=null;  private Node Pointer=null;  private int Length=0;  public void deleteAll()  /*清空整个链表*/  {   Head=null;   Tail=null;   Pointer=null;   Length=0;  }  public void reset()  /*链表复位,使第一个结点成为当前结点*/  {   Pointer=null;  }  public boolean isEmpty()  /*判断链表是否为空*/  {   return(Length==0);  }  public boolean isEnd()  /*判断当前结点是否为最后一个结点*/  {   if(Length==0)    throw new Java.lang.NullPointerException();   else if(Length==1)    return true;   else    return(cursor()==Tail);  }  public Object nextNode()  /*返回当前结点的下一个结点的值,并使其成为当前结点*/  {   if(Length==1)    throw new Java.util.NoSuchElementException();   else if(Length==0)    throw new Java.lang.NullPointerException();   else   {    Node temp=cursor();    Pointer=temp;    if(temp!=Tail)     return(temp.next.data);    else     throw new Java.util.NoSuchElementException();   }  }  public Object currentNode()  /*返回当前结点的值*/  {   Node temp=cursor();   return temp.data;  }     public void insert(Object d)  /*在当前结点前插入一个结点,并使其成为当前结点*/  {   Node e=new Node(d);   if(Length==0)   {    Tail=e;    Head=e;   }   else   {    Node temp=cursor();    e.next=temp;    if(Pointer==null)     Head=e;    else     Pointer.next=e;   }   Length++;  }  public int size()  /*返回链表的大小*/  {   return (Length);  }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜到极致就是渣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值