其他分享
首页 > 其他分享> > 链表

链表

作者:互联网

链表的概念:

链表属于一种数据结构,链表可以保存多个数据,以节点的形式出现,每个节点都可以保存数据,而且每个节点除了可以保存数据之外还必须有对下一个节点的引用
在这里插入图片描述
链表是HashMap的实现原理之一,是HashMap的基础

public class NodeDemo02 {
    public static void main(String[] args) {
        //创建出节点
        Node<String> root = new Node<String>("火车头");
        Node<String> n1 = new Node<String>("车厢A");
        Node<String> n2 = new Node<String>("车厢B");
        Node<String> n3 = new Node<String>("车厢C");
        //维护节点之间的关系
        root.setNextNode(n1);
        n1.setNextNode(n2);
        n2.setNextNode(n3);
        //输出节点数据
        Node<String> cuurentNode = root;
        while(cuurentNode != null) {
            System.out.print(cuurentNode.getData() + "--->");
            cuurentNode = cuurentNode.getNextNode();
        }
    }
}
class  Node<T>{
    private  T data;
    private  Node  nextNode;
    public   Node(){
    }
    public   Node(T  data){
        this.data=data;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public Node getNextNode() {
        return nextNode;
    }
    public void setNextNode(Node nextNode) {
        this.nextNode = nextNode;
    }
}

在这里插入图片描述
以上是使用while输出数据,那么最好的方式不是while循环而是递归输出

public class NodeDemo02 {
    public static void main(String[] args) {
        //创建出节点
        Node<String> root = new Node<String>("火车头");
        Node<String> n1 = new Node<String>("车厢A");
        Node<String> n2 = new Node<String>("车厢B");
        Node<String> n3 = new Node<String>("车厢C");
        //维护节点之间的关系
        root.setNextNode(n1);
        n1.setNextNode(n2);
        n2.setNextNode(n3);
        //调用递归输出节点数据
        print(root);
    }
    /**
     *  递归输出节点数据
     * @param currentNode
     */
    public  static  void  print(Node  currentNode){
        if(currentNode==null){
            return ;
        }
        System.out.print(currentNode.getData()+"--->");
        print(currentNode.getNextNode());
    }

}
class  Node<T>{
    private  T data;
    private  Node  nextNode;
    public   Node(){
    }
    public   Node(T  data){
        this.data=data;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public Node getNextNode() {
        return nextNode;
    }
    public void setNextNode(Node nextNode) {
        this.nextNode = nextNode;
    }
}

在这里插入图片描述
以上对节点的操作都是在主方法中实现,也据说节点的创建,关系维护,输出都是在主方法中实现的,我们说过主方法是客户端,在客户端要求代码尽可能的简洁,不要出现这些复杂的操作,后面我们会将这些操作封装影藏不出现在主方法中
需要使用一个中间类来维护客户端和节点之间的交互,和二叉树类似,节点是被封装到一个BinaryTree中了,那么这个外部类BinaryTree就是节点和客户端之间的一个中间类,客户端不能直接操作节点的类,而是通过BinaryTree类去操作

public class NodeDemo02 {
    public static void main(String[] args) {
        Link<String> link = new Link<String>();
        link.add("JavaScript开发大全");
        link.add("数据库从删库到跑路");
        link.add("Java从入门到放弃");
        link.add("毛泽东思想概论");
        link.print();
    }
    /**
     *  递归输出节点数据
     * @param currentNode
     */
    public  static  void  print(Node  currentNode){
        if(currentNode==null){
            return ;
        }
        System.out.print(currentNode.getData()+"--->");
        print(currentNode.getNextNode());
    }

}
class  Node<T>{
    private  T data;
    private  Node  nextNode;
    public   Node(){
    }
    public   Node(T  data){
        this.data=data;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public Node getNextNode() {
        return nextNode;
    }
    public void setNextNode(Node nextNode) {
        this.nextNode = nextNode;
    }
    //添加节点数据
    public void addNewNode(Node<T> newNode) {
        //判断当前节点是否为null
        if (this.nextNode == null) {
            this.nextNode = newNode;
        } else {
            this.nextNode.addNewNode(newNode);
        }
    }
    //输出节点的数据
    public void printNode() {
        System.out.println(this.data);
        if (this.nextNode != null) {
            this.nextNode.printNode();
        }
    }
}
class Link<T> {
    private Node<T> root; //表示链表的根节点
    int foot = 0; //用来记录节点的下标
    /**
     * Link 中的添加数据的方法
     * @param data
     */
    public void add(T data) {
        Node<T> newNode = new Node<T>(data);
        if (this.root == null) {
            this.root = newNode;
        }else {
            this.root.addNewNode(newNode);
        }
    }
    public void print() {
        if (this.root == null) {
            return;
        } else {
            this.root.printNode();
        }
    }
}

在这里插入图片描述

将Node设置为内部类:

Link 的本质作用是将Node类和客户端之间的数据交互操作封装隐藏了,但是严格的做法不能在Link类之外访问Node类,也就是要让Node类依赖于Link类,但是此时我们还可以在客户端上直接访问Node类的,这是不够严谨的,为了解决这一问题,我们需要将Node类定义为Link类的私有内部类,这样的好处是什么呢?

package com.sxt;

public class Test {
    public static void main(String[] args) {
        //添加数据
        Link<String>  link=new Link<String>();
        link.add("JavaScript开发大全");
        link.add("数据库从删库到跑路");
        link.add("Java从入门到放弃");
        link.add("毛泽东思想概论");
        //输出数据
        link.print();
    }
}
//定义出Link类
class Link<T>{
    private class  Node<T>{ //定义了内部类
        private  T data;
        private  Node  nextNode;
        public   Node(){
        }
        public   Node(T  data){
            this.data=data;
        }
        public T getData() {
            return data;
        }
        public void setData(T data) {
            this.data = data;
        }
        public Node getNextNode() {
            return nextNode;
        }
        public void setNextNode(Node nextNode) {
            this.nextNode = nextNode;
        }
        //添加节点数据
        public   void  addNewNode(Node<T>  newNode){
            //判断当前节点的下一个节点是否为null
            if(this.nextNode==null){
                this.nextNode=newNode;
            }else{
                this.nextNode.addNewNode(newNode);
            }
        }
        //输出节点的数据
        public  void   printNode(){
            System.out.println(this.data);
            if(this.nextNode!=null){
                this.nextNode.printNode();
            }
        }
    }
    //以下代码是外部类中的代码
    private  Node<T> root;//表示链表的根节点
    int foot=0;// 用来记录节点的下标
    /**
     * Link中的添加数据的方法
     * @param data
     */
    public  void  add(T data){
        Node<T>  newNode=new Node<T>(data);
        if(this.root==null){
            this.root=newNode;
        }else{
          this.root.addNewNode(newNode);
        }
    }
    /**
     * 输出数据
     */
    public  void  print(){
         if(this.root==null){
             return ;
         }else{
             this.root.printNode();
         }
    }
}

在这里插入图片描述
取得链表长度:
在Link类中定义一个变量来保存节点的个数,每次调用addNode()方法就让变量加一即可

package com.sun;
//定义出Link类
class Link<T>{
    private class  Node<T>{ //定义了内部类
        private  T data;
        private  Node  nextNode;
        public   Node(){
        }
        public   Node(T  data){
            this.data=data;
        }
        public T getData() {
            return data;
        }
        public void setData(T data) {
            this.data = data;
        }
        public Node getNextNode() {
            return nextNode;
        }
        public void setNextNode(Node nextNode) {
            this.nextNode = nextNode;
        }
        //添加节点数据
        public   void  addNewNode(Node<T>  newNode){
            //判断当前节点的下一个节点是否为null
            if(this.nextNode==null){
                this.nextNode=newNode;
            }else{
                this.nextNode.addNewNode(newNode);
            }
        }
        //输出节点的数据
        public  void   printNode(){
            System.out.println(this.data);
            if(this.nextNode!=null){
                this.nextNode.printNode();
            }
        }
    }
    //以下代码是外部类中的代码>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    private  Node<T> root;//表示链表的根节点
    private  int   count=0;//保存节点个数(链表长度)
    int foot=0;// 用来记录节点的下标
    /**
     * Link中的添加数据的方法
     * @param data
     */
    public  void  add(T data){
        Node<T>  newNode=new Node<T>(data);
        if(this.root==null){
            this.root=newNode;
        }else{
          this.root.addNewNode(newNode);
        }
        this.count++;
    }
    /**
     * 输出数据
     */
    public  void  print(){
         if(this.root==null){
             return ;
         }else{
             this.root.printNode();
         }
    }
    /**
     * 取得链表长度
     * @return
     */
    public  int  size(){
        return this.count;
    }
}
public class Test {
    public static void main(String[] args) {
        //添加数据
        Link<String>  link=new Link<String>();
        link.add("JavaScript开发大全");
        link.add("数据库从删库到跑路");
        link.add("Java从入门到放弃");
        link.add("毛泽东思想概论");
        //输出数据
        System.out.println("链表长度是:"+link.size());
    }
}

在这里插入图片描述
判断链表是否为null:

/**
 *  判断链表是否为空
 * @return  如果为空返回  true   否则就是返回false
 */
public   boolean  isEmpty(){
    return  this.count==0;
}

在外部类中添加方法

public class Test {
    public static void main(String[] args) {
        //添加数据
        Link<String>  link=new Link<String>();
        link.add("JavaScript开发大全");
        link.add("数据库从删库到跑路");
        link.add("Java从入门到放弃");
        link.add("毛泽东思想概论");
        //输出数据
        System.out.println("链表长度是:"+link.size());
        System.out.println("链表是否为空:"+link.isEmpty());
    }
}

在这里插入图片描述

标签:Node,void,nextNode,节点,链表,data,public
来源: https://blog.csdn.net/qq_42539533/article/details/87918313