Java学习笔记之链表

链表是一种非常常见和重要的数据结构,在java里也可以通过引用传递的方式进行实现。

1、基本概念

什么是链表,通俗的可以理解为一辆货车,火车头代表链表表头,后面的每一节车厢表示一个链表的结点,每一个结点除了存储本节点的数据以外,还得带上下一个结点的引用,也就是除了车尾以外的那些车厢,都必须连接后面的一节车厢。

在这里插入图片描述

2、链表的实现

要实现链表,我们必须定义一个链表类,在类中还得有一个属性,可以保存下一个节点的引用地址。

每一个节点除了要存储当前节点的数据,还得带上下一个结点的引用地址。

class Node{
    private String data;  // 节点的数据
    private Node next;    // 下一个节点的引用地址
    public Node(String data){  // 构造函数设置节点内容
        this.data = data;
    }

    public Node getNext() {
        return this.next;    // 获取下一个节点
    }

    public void setNext(Node next) {
        this.next = next;       // 设置下一个节点
    }

    public String getData(){
        return this.data;
    }
}

public class LinkDemo {
    public static void main(String[] args) {
        Node root = new Node("火车头");
        Node node1 = new Node("一号车厢");
        Node node2 = new Node("二号车厢");
        Node node3 = new Node("三号车厢");
        root.setNext(node1);
        node1.setNext(node2);
        node2.setNext(node3);
        printNode(root);  // 从头开始输出
    }

    public static void printNode(Node node) {
        System.out.print(node.getData()+" -> ");
        if(node.getNext()!=null){
            printNode(node.getNext());  // 递归调用节点
        }
    }
}

上述例子中,所有的关系都是用户手动设置,如果想让它真正有意义,我们需要加入一个操作的封装。

2、链表的改进

可以看到,上面的实现的链表需要人工手动去操作节点,一个个添加,一个个处理引用关系,非常繁琐,因此我们应该将对节点的操作进行封装。常见的操作有:增加数据、查找数据、删除数据。
注意:删除数据其实只是改变节点引用地址而已

在这里插入图片描述

  • 增加节点:在链表最后追加
  • 查找节点:递归查找
  • 删除节点:修改引用关系
2.1 新增节点
class Link{ // 链表的完成类
    class Node{ // 节点类
        private String data;
        private Node next;
        public Node(String data){
            this.data = data;
        }

        public void add(Node newNode){ // 将节点加入到合适的位置
            if(this.next==null){  // 如果下一个节点为空,则把新节点设置在next位置
                this.next = newNode;
            }else{   // 如果下一节点非空,则继续向后递归查找
                this.next.add(newNode);
            }
        }

        public void print(){
            System.out.print(this.data + " -> ");  // 输出节点内容
            if(this.next!=null){        // 判断是否为最后一个节点,若不是则继续递归调用
                this.next.print();
            }
        }
    }

    private Node root;   // 设置根节点
    public void addNode(String data){   // 增加节点
        Node newNode = new Node(data);  // 定义新的节点
        if(this.root==null){    // 如果根节点为空,则设置 newNode 为根节点
            this.root = newNode;
        }else{                  // 如果不是根节点,利用add方法把节点放在合适的位置
            this.root.add(newNode);
        }

    }

    public void printNode(){    // 输出链表内容
        if(this.root!=null){    // 如果链表根元素不为空
            this.root.print();  // 调用Node类中的输出操作
        }
    }


}

public class LinkDemo2 {
    public static void main(String[] args) {
        Link link = new Link();
        link.addNode("A");	  // 增加节点
        link.addNode("B");
        link.addNode("C");
        link.addNode("D");
        System.out.println("------------------");
        link.printNode();
    }
}
2.2 查找节点
class Link{ // 链表的完成类
    class Node{ // 节点类
        private String data;
        private Node next;
        public Node(String data){
            this.data = data;
        }

        public void add(Node newNode){ // 将节点加入到合适的位置
            if(this.next==null){  // 如果下一个节点为空,则把新节点设置在next位置
                this.next = newNode;
            }else{   // 如果下一节点非空,则继续向后递归查找
                this.next.add(newNode);
            }
        }

        public void print(){
            System.out.print(this.data + " -> ");  // 输出节点内容
            if(this.next!=null){        // 判断是否为最后一个节点,若不是则继续递归调用
                this.next.print();
            }
        }

        public boolean search(String data){  // 内部搜索方法
            if(data.equals(this.data)){      // 判断当前节点数据和查找数据是否一致
                return true;
            }else{      // 继续向后判断
                if(this.next!=null){         // 如果下一个节点存在,继续判断是否数据相等
                    return this.next.search(data);
                }else{                       // 否则返回失败
                    return false;
                }
            }
        }


    }

    private Node root;   // 设置根节点
    public void addNode(String data){   // 增加节点
        Node newNode = new Node(data);  // 定义新的节点
        if(this.root==null){    // 如果根节点为空,则设置 newNode 为根节点
            this.root = newNode;
        }else{                  // 如果不是根节点,利用add方法把节点放在合适的位置
            this.root.add(newNode);
        }

    }

    public void printNode(){    // 输出链表内容
        if(this.root!=null){    // 如果链表根元素不为空
            this.root.print();  // 调用Node类中的输出操作
        }
    }

    public boolean contains(String name){   // 判断元素是否存在
        return this.root.search(name);
    }


}

public class LinkDemo2 {
    public static void main(String[] args) {
        Link link = new Link();
        link.addNode("A");
        link.addNode("B");
        link.addNode("C");
        link.addNode("D");
        System.out.println("------------------");
//        link.printNode();
        System.out.println(link.contains("X"));
    }
}
2.3 删除节点
class Link{ // 链表的完成类
    class Node{ // 节点类
        private String data;
        private Node next;
        public Node(String data){
            this.data = data;
        }

        public void add(Node newNode){ // 将节点加入到合适的位置
            if(this.next==null){  // 如果下一个节点为空,则把新节点设置在next位置
                this.next = newNode;
            }else{   // 如果下一节点非空,则继续向后递归查找
                this.next.add(newNode);
            }
        }

        public void print(){
            System.out.print(this.data + " -> ");  // 输出节点内容
            if(this.next!=null){        // 判断是否为最后一个节点,若不是则继续递归调用
                this.next.print();
            }
        }

        public boolean search(String data){  // 内部搜索方法
            if(data.equals(this.data)){      // 判断当前节点数据和查找数据是否一致
                return true;
            }else{      // 继续向后判断
                if(this.next!=null){         // 如果下一个节点存在,继续判断是否数据相等
                    return this.next.search(data);
                }else{                       // 否则返回失败
                    return false;
                }
            }
        }

        public void delete(Node previous, String data){
            if(data.equals(this.data)){     // 找到匹配的节点
                previous.next = this.next;  // 空出当前节点
            }else{
                if(this.next!=null){        // 还是存在下一个节点
                    this.next.delete(this, data);
                }
            }
        }


    }

    private Node root;   // 设置根节点
    public void addNode(String data){   // 增加节点
        Node newNode = new Node(data);  // 定义新的节点
        if(this.root==null){    // 如果根节点为空,则设置 newNode 为根节点
            this.root = newNode;
        }else{                  // 如果不是根节点,利用add方法把节点放在合适的位置
            this.root.add(newNode);
        }

    }

    public void printNode(){    // 输出链表内容
        if(this.root!=null){    // 如果链表根元素不为空
            this.root.print();  // 调用Node类中的输出操作
        }
    }

    public boolean contains(String name){   // 判断元素是否存在
        return this.root.search(name);
    }

    public void deleteNode(String data){
        if(this.contains(data)){  // 判断节点是否存在
            // 一定要判断此元素是否和根节点相等
            if(this.root.data.equals(data)){    // 内容是根节点
                this.root = this.root.next;     // 修改根节点,把第一个节点设置为根节点
            }else{
                this.root.next.delete(root, data);      // 把下一个节点的前节点和数据传入继续判断
            }

        }
    }


}

public class LinkDemo2 {
    public static void main(String[] args) {
        Link link = new Link();
        link.addNode("A");
        link.addNode("B");
        link.addNode("C");
        link.addNode("D");
        System.out.println("--------- 删除之前 ---------");
        link.printNode();
//        System.out.println(link.contains("X"));
        link.deleteNode("C");
        link.deleteNode("B");
        link.deleteNode("A");
        System.out.println();
        System.out.println("--------- 删除之后 ---------");
        link.printNode();
        System.out.println();
        System.out.println("查找节点D: " + link.contains("D"));
    }
}

猜你喜欢

转载自blog.csdn.net/zuolixiangfisher/article/details/84845136