java自制链表

java自制链表

请添加图片描述

简言

众所周知,java自身库是有包涵链表的,但是有的数据结构老师和算法老师可能会让学生自己写链表。这里就演示个简单的单链表和双链表,并实现链表的增删改基础功能。

理论

链表的话,可以先进先出,后进先出。可以把链表看成杯子,杯口就叫他它head,杯底叫tail
先进先出(head进tail出)
请添加图片描述

后进先出(head进head出)
请添加图片描述

实现
  • 定义链表和节点
class LinkList{
    private Node head;
    private Node tail;
    private int size;
}
class Node{
    String value;
    Node next;
    public Node(String val){
        this.value=val;
    }
    public Node(String val,Node next){
        this.next=next;
        this.value=val;
    }
    public Node(){}
}
  • 增加节点
public void add(Node node){
	if(this.head==null&&this.tail==null){
	    this.head=node;
	    this.tail=node;
	}else{
	    node.next=this.head;
	    this.head=node;
	}
	size++;
}
public boolean addafter(Node nodeone,Node nodetwo){
   Node pre=this.head;
    while(pre.value!=nodeone.value){
        pre=pre.next;
    }
    if (pre.value!=nodeone.value){
        return false;
    }
    if(pre.next==null){
        pre.next=nodetwo;
    }else{
        Node buffernode=pre.next;
        pre.next=nodetwo;
        nodetwo.next=buffernode;
    }
    return true;
}

由于加入节点是从head端加的且为单链表,所以第一个节点进来的时候tail就和第一个节点绑定了,后面除了删除tail节点会导致tail节点变更,不然后续操作tail节点都不会动。至于addafter方法,则为在链表中指定节点后面加入新节点,若指定节点在链表中不存在,则返回false,成功在指定节点添加返回true。

  • 查找节点
public Node get(int index){
    if(index>=this.size){
        return null;
    }
    int virsize=this.size-1;
    Node headadd=this.head;
    while(virsize!=index){
        headadd=headadd.next;
        virsize--;
    }
    return headadd;

}
public int get(String value){
    if (this.size<1){
        return -1;
    }
    Node headadd=this.head;
    int virsize=this.size-1;
    while (!headadd.value.equals(value)&&headadd.next!=null) {
        headadd=headadd.next;
        virsize--;
    }
    if(!headadd.value.equals(value)){
        return -1;
    }else{
        return virsize;
    }
}

这里有两个get方法,第一个通过位置返回节点,第二个通过节点值返回位置。

  • 删除节点
    链表原型请添加图片描述
public void deletefirst(){
    if(this.head!=null){
        if(this.head.next!=null){
            this.head=this.head.next;
        }else{
            this.head=null;
            this.tail=null;
        }
        this.size--;
    }
}
public void deletelast(){
    Node headadd=this.head;
    if (headadd!=null) {
        if (headadd.next!=null){
            while (headadd.next.next!=null) {
                headadd=headadd.next;
            }
            this.tail=headadd;
            headadd.next=null;
        }else{
            this.head=null;
            this.tail=null;
        }
        this.size--;
    }
}

这里可以看出我们删除节点有两种方法。deletefirst是从原型图中的head端开始删除(由于我们这里是单链表,只需把head标向下移一位就删除顶部节点了)。deletelast则是从tail开删,所以在tail标上移一位过后,还需申明tail没有下一位节点。

测试链表
public class Tutorial {
    public static void main(String[] args) {
        LinkList list=new LinkList();
        list.add(new Node("im first in"));
        list.add(new Node("im second in"));
        list.add(new Node("im third in"));
        list.addafter(new Node("im first in"), new Node("im last in"));
        list.printList();
        list.deletelast();
        list.printList();
        System.out.println(list.get(2).value);
        System.out.println(list.get("im second in"));
    }
}

测试结果
请添加图片描述
完整代码

public class Tutorial {
    public static void main(String[] args) {
        LinkList list=new LinkList();
        list.add(new Node("im first in"));
        list.add(new Node("im second in"));
        list.add(new Node("im third in"));
        list.addafter(new Node("im first in"), new Node("im last in"));
        list.printList();
        list.deletelast();
        list.printList();
        System.out.println(list.get(2).value);
        System.out.println(list.get("im second in"));
    }
}
class Node{
    String value;
    Node next;
    public Node(String val){
        this.value=val;
    }
    public Node(String val,Node next){
        this.next=next;
        this.value=val;
    }
    public Node(){}
}
class LinkList{
    private Node head;
    private Node tail;
    private int size;
    public LinkList(Node head){
        this.head=head;
    }
    public LinkList(){}
    public void add(Node node){
        if(this.head==null&&this.tail==null){
            this.head=node;
            this.tail=node;
        }else{
            node.next=this.head;
            this.head=node;
        }
        this.size++;
    }
    public boolean addafter(Node nodeone,Node nodetwo){
        Node pre=this.head;
        while(pre.value!=nodeone.value){
            pre=pre.next;
        }
        if (pre.value!=nodeone.value){
            return false;
        }
        if(pre.next==null){
            pre.next=nodetwo;
        }else{
            Node buffernode=pre.next;
            pre.next=nodetwo;
            nodetwo.next=buffernode;
        }
        this.size++;
        return true;
    }
    public Node get(int index){
        if(index>=this.size){
            return null;
        }
        int virsize=this.size-1;
        Node headadd=this.head;
        while(virsize!=index){
            headadd=headadd.next;
            virsize--;
        }
        return headadd;

    }
    public int get(String value){
        if (this.size<1){
            return -1;
        }
        Node headadd=this.head;
        int virsize=this.size-1;
        while (!headadd.value.equals(value)&&headadd.next!=null) {
            headadd=headadd.next;
            virsize--;
        }
        if(!headadd.value.equals(value)){
            return -1;
        }else{
            return virsize;
        }
    }
    public void deletefirst(){
        if(this.head!=null){
            if(this.head.next!=null){
                this.head=this.head.next;
            }else{
                this.head=null;
                this.tail=null;
            }
            this.size--;
        }
    }
    public void deletelast(){
        Node headadd=this.head;
        if (headadd!=null) {
            if (headadd.next!=null){
                while (headadd.next.next!=null) {
                    headadd=headadd.next;
                }
                this.tail=headadd;
                headadd.next=null;
            }else{
                this.head=null;
                this.tail=null;
            }
            
            this.size--;
        }
    }
    @Override
    public String toString(){
        StringBuilder sbf=new StringBuilder();
        Node node=this.head;
        while(node!=null){
            sbf.append(node.value);
            node=node.next;
        }
        return sbf.toString();
    }
    public void printList(){
        StringBuilder sbf=new StringBuilder();
        Node node=this.head;
        while(node!=null){
            sbf.append(node.value);
            sbf.append("=>");
            node=node.next;
        }
        sbf.append("end");
        System.out.println(sbf.toString());
    }
}
结语
  • 关于双链表
    这是两个链表的底层(node)。也就是说双链表相较于单链表来讲,非头尾节点的话,需互相绑定,但双链表比单链表找节点更灵活,甚至可以头尾一起找节点
    请添加图片描述
    请添加图片描述
    在此基础上堆栈的实现,请点击这里跳跃
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值