单链表的那些事

单链表是我们非常熟悉也是一种删除和插入效率极高的数据结构,它存储数据非常密集。不过它的缺点也是比较明显,那就是查询的速度比较慢。因为它不像数组那样有一连串的下标可以直接进行
遍历查询。即使是这样,单链表也是非常重要的数据结构。本篇文章主要是最直观的反应出单链表是一个怎样的结构和它底层的一些实现,这些也有助于我们对源码进行学习。
链表的主要操作就是增加和删除,而添加数据(后面将用节点代替)也有两种添加的方式。第一种是尾插发,第二种是头插法。下面将分别展示这两种添加节点(本篇文章使用带头节点的链表
并且每个节点有两个域,一个是值域,一个是存放下一个节点的)的方法。
尾插法:可以理解为就是不断的在链表最后添加数据,让前一个节点的next指针指向下一个节点。
但需要注意的是做该操作的时候需要用到辅助指针。
其核心的代码就是不断的添加节点,然后在向后移动辅助指针。

 

 

 头插法:可以理解为就是不断的在最前面添加节点,并且和尾插法添加数据的顺序正好是相反。

                同样的也需要一个辅助指针进行遍历操作。

 

 

 

 

 

 

 主要的代码如下:

public class List {
    public static void main(String[] args) {
        Node node = new Node(0, "小红");
        SingleList singleList = new SingleList();
        //singleList.Add(node);

        Node node1 = new Node(3, "Abel");
        //singleList.Add(node1);

        Node node2 = new Node(5, "柯柯");
        //singleList.Add(node2);

        Node node3 = new Node(2, "峰峰");
        //singleList.Add(node3);

        Node node4 = new Node(6, "普拉达");
        //singleList.Add(node4);

        //Node node5 = new Node(6, "拉大");
       // singleList.AddByNumber(node5);
        //Node node5 = new Node(2, "峰哥");
       // singleList.updateByNumber(node5);
        //singleList.show();
        //singleList.totalNode();
        //Node head = new Node();
        singleList.touChaFa(node);
        singleList.touChaFa(node1);
        singleList.touChaFa(node2);
        singleList.touChaFa(node3);
        singleList.touChaFa(node4);
        System.out.println();
        singleList.show();
       // singleList.totalNode();
        //System.out.println("删除之后的链表");
        //singleList.deleteByNumber(6);
        //singleList.show();
        //singleList.totalNode();
        //singleList.queryByNumber(2);
    }

}
class SingleList{
    private final Node head=new Node();

    /**
     * 头插法,将单链表逆置
     * @param node
     */
    public void touChaFa(Node node){
        // 判断链表是否为空,如果为空,则将head.next指向node
        if (head.nextNode == null) {
            head.nextNode= node;
            return;
        }
            // 如果链表不为空,找到head.next,将node插入head和head.next之间
            Node temp = head.nextNode;
            head.nextNode = node;  // head.next指向node
            node.nextNode = temp;  // node.next指向之前的head.next

    }

    /**
     * 查看该单链表有几个节点
     */
    public int totalNode(){
        if(head.nextNode==null){
            System.out.println("该链表为空");
        }
        int i=0;
        //定义辅助指针
        Node temp=head;
        while (true){
            if(temp.nextNode==null){
                break;
            }
            i++;
            temp=temp.nextNode;
        }
        return i;
    }

    /**
     * 根据number删除数据
     * @param number
     */
    public void deleteByNumber(int number){
        //判断链表是否为空
        if(head.nextNode==null){
            System.out.println("该链表为空");
            return;
        }
        //定义一个辅助指针
        Node temp=head;
        //设立标志
        boolean flag=true;
        //遍历该单链表
        while (true){
            if(temp.nextNode.number==number){
                flag=false;
                break;
            }
            temp=temp.nextNode;
        }

        if(flag){
            System.out.println("没有找到该节点");
        }else {
            temp.nextNode=temp.nextNode.nextNode;
        }
    }

    /**
     * 根据number查询数据
     * @param number
     */
    public void queryByNumber(int number){
        if(head.nextNode==null){
            System.out.println("该单链表为空");
            return;
        }
        //定义一个辅助指针
        Node temp=head;
        //定义一个标志
        boolean flag=true;
        //开始遍历单链表
        while (true){
            //找到该节点
            if(temp.nextNode.number==number){
                flag=false;
                break;
            }
            temp=temp.nextNode;
        }

        if(flag){
            System.out.println("该节点不存在");
        }else {
            System.out.println();
            System.out.println("你要找节点为"+number+"的数据为:"+temp.nextNode.data);
        }
    }

    /**
     * 根据节点修改相应的数据
     * @param node
     */
    public void updateByNumber(Node node){
        //定义应该辅助指针
        Node temp=head;
        //遍历该单链表、
        while (true){
            if(temp.nextNode==null){
                //System.out.println("该单链表为空");
                break;
            }
            if(temp.nextNode.number==node.number){
                temp.nextNode.data=node.data;
                break;
            }
            temp=temp.nextNode;
        }
    }

    /**
     * 根据它的number大小来添加数据
     * @param node
     */
    public void AddByNumber(Node node){
        //定义辅助指针
        Node temp=head;
        //定义一个标志
        boolean flag=true;
        while (true){
            if(temp.nextNode==null){
                //说明没有找到
                break;
            }
            if(temp.nextNode.number>node.number){
                //说明找到了
                break;
            }else if(temp.nextNode.number==node.number){
                //说明要插入的数据已经存在了
                flag=false;
                break;
            }
            //不符合则往后遍历
            temp=temp.nextNode;
        }
        if(flag){
            //开始添加数据
            node.nextNode=temp.nextNode;
            temp.nextNode=node;
        }else {
            System.out.println("该数据已经存在");
        }
    }

    /**
     * 添加节点
     * @param node
     */
    public void Add(Node node){
        //定义辅助指针
        Node temp=head;
        //开始遍历链表和添加节点
        while (true){
            if(temp.nextNode==null){
                //说明该链表目前为止是空链表
                temp.nextNode=node;
                break;
            }
            //如果不为空则继续向后遍历
            temp=temp.nextNode;
        }
    }

    /**
     * 显示链表所有的数据
     */
    public void show(){
        //判断为空
        if(head.nextNode==null){
            return;
        }
        //定义一个辅助指针
        Node temp=head.nextNode;
        while (true){
            if(temp==null){
                /*System.out.print("["+temp.number+"-"+temp.data+"]"+"->");*/
                //System.out.println("该节点为空");
                break;
            }
            System.out.print("["+temp.number+"-"+temp.data+"]"+"->");
            temp=temp.nextNode;
        }
    }
}

class Node{
    public int number;
    public String data;
    public Node nextNode;

    public Node(int number, String data) {
        this.number = number;
        this.data = data;
    }

    public Node(){}

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public String getData() {
        return data;
    }

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

    public Node getNextNode() {
        return nextNode;
    }

    public void setNextNode(Node nextNode) {
        this.nextNode = nextNode;
    }

    @Override
    public String toString() {
        return "Node{" +
                "number=" + number +
                ", data='" + data + '\'' +
                '}';
    }
}

 

posted @ 2021-01-25 16:07  诸葛孔俺  阅读(112)  评论(0)    收藏  举报