Java实现链表

首先定义一个节点

public class Node {
    private  int data; // 节点值
    private Node next; // 指向下一个节点的指针

    public Node(int data){
        this.data = data;
    }
    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

也可以复杂一点

这里只用到最简单的data为int型的节点。

然后定义一个链表类封装链表的操作,链表类里需要一个头节点。

package com.example.demo.LinkedList;

/**
 * @author MasterYi
 * @Description: 单链表
 * @date: 2019/11/8
 */
public class MyLinkedList {
    private Node head; // 首先要有一个头节点

    public MyLinkedList(){}

    // 构造方法
    // 将一个头节点传进来 构造出一个链表 此时链表里只有一个头节点
    public MyLinkedList(Node head){
        this.head = head;
    }

    // 求链表长度
    public int getLength(){
        // 头节点为空时,长度为0
        int length = 0;
        for(Node node = this.head;node!=null;node=node.getNext()){
            length ++;
        }
       return length;
    }

    /**
     * 找出第index节点,index从0开始
     * @param index
     * @return
     */
    public Node findNodeByIndex(int index){
        if(index+1 > this.getLength()){
            return null;
        }
        Node retNode = this.head;
        for(int i=0;i<this.getLength();i++){
            if(i == index){
                return retNode;
            }
            retNode=retNode.getNext();
        }
        return null;
    }

    /**
     * 遍历链表并打印
     */
    public void printList(){
        for(Node node=this.head;node!=null;node=node.getNext()){
            System.out.println("node data:"+node.getData());
        }
        System.out.println("-------------------");
    }

    /**
     * 找出下一个节点
     * @param curNode
     * @return
     */
    public Node findNext(Node curNode){
        if(null == curNode){
            return null;
        }
        return curNode.getNext();
    }

    /**
     * 找出上一个节点
     * @param curNode
     * @return
     */
    public Node findLast(Node curNode){
        if(null == curNode || 0 == this.getLength()){
            return null;
        }
        Node lastNode = null;
        for(lastNode=this.head;lastNode.getNext()!=curNode;lastNode=lastNode.getNext()){}
        return lastNode.getNext()==curNode? lastNode : null;
    }

    /**
     * 向尾部添加一个节点
     * @param addNode
     * @return
     */
    public boolean addNodeTail(Node addNode){
        // 头节点为空 插入的节点就是头节点
        if(0 == this.getLength()){
            this.head = addNode;
        }else{
            Node tail = this.head; // 尾部节点
            // 找到最后一个节点
            for (;tail.getNext()!=null;tail=tail.getNext()){}
            tail.setNext(addNode);
        }
       return true;
    }

    /**
     * 在尾部删除一个节点
     * @return
     */
    public boolean delNodeTail(){
        if(0 == this.getLength()){
            return false;
        }
        Node tail;
        for(tail = this.head;tail.getNext()!=null;tail=tail.getNext()){}
        this.findLast(tail).setNext(null); // 将前一个节点的next指针指向null
        return true;
    }

    /**
     * 在当前节点后面新增一个节点
     * @param curNode
     * @return
     */
    public boolean addNode(Node curNode,Node newNode){
        if(0 == this.getLength()){
            return false;
        }
        Node nowNode;
        for(nowNode = this.head;nowNode!=curNode;nowNode=nowNode.getNext()){}
        if(nowNode == curNode){
            // 新节点的next指向当前的后面节点
            // 当前节点的next指向新节点
            newNode.setNext(nowNode.getNext());
            nowNode.setNext(newNode);
            return true;
        }else {
            // 没有找到当前节点
            return false;
        }
    }

    /**
     * 删除当前节点
     * @param curNode
     * @return
     */
    public boolean delNode(Node curNode){
        Node nowNode = this.head;
        for(int i=0;nowNode!=curNode && i<this.getLength();i++){
            nowNode = nowNode.getNext();
        }
        // 没有找到此节点
        if(null == nowNode ){
            return false;
        }
        // 将当前节点的上一个节点的next设为下一个节点的next
        this.findLast(nowNode).setNext(nowNode.getNext());
        return true;
    }

}

测试

public class TestMain {
    public static void main(String[] args) {
        MyLinkedList myLinkedList = new MyLinkedList();
        Node head = new Node(1);
        myLinkedList.addNodeTail(head);
        myLinkedList.addNodeTail(new Node(2));
        myLinkedList.addNodeTail(new Node(3));
        myLinkedList.addNodeTail(new Node(4));
        myLinkedList.addNodeTail(new Node(5)); // 向链表里往尾部插入5个节点 现在链表长度为5
        myLinkedList.printList();
        myLinkedList.delNodeTail(); // 删除尾部的一个节点,现在长度为4
        myLinkedList.printList();
        Node curNode = myLinkedList.findNodeByIndex(2);
        Node node999 = new Node(999);
        myLinkedList.addNode(curNode,node999); // 往第二个节点的后面插入一个新节点
        myLinkedList.printList();
        myLinkedList.delNode(node999); // 删除这个新节点
        myLinkedList.printList();

    }
}

测试结果:

以上为单链表的实现。单链表是指节点里只有数据域(data)和指向下一节点的指针(next)

单链表可以在O(1)的时间内找到当前节点的下一节点(直接调用node.getNext()),但需要O(n)的时间来找出上一节点(需要从头节点开始遍历,findLast()方法体现了这个问题)

双向链表指不仅仅有数据域、下一节点的指针、还有上一节点的指针,只需要在Node类里增加一个指向上一节点的指针(pre),同时修改findLast()为node.getPre()即可。

此外还有环形链表(最后一个节点的指针指向头节点),

环形链表又分双向环形链表和单项环形链表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值