初级链表简单案例—java版

话不多说,上代码,下面我说一下几个核心思想,其他的代码小伙伴应该能看明白

package com.gaojiale.LinkedList;

public class SingleLinkedList {
    public static void main(String[] args) {
        LinkListOptions linkListOptions = new LinkListOptions();
        Node Head = linkListOptions.init();
        Node newNode1 = new Node(1,"张三");
        Node newNode2 = new Node(2,"李四");
        linkListOptions.add(Head,newNode1);
        linkListOptions.add(Head,newNode2);
        linkListOptions.Traverse(Head);
    }
}
    //管理结点类
    class LinkListOptions{
        public LinkListOptions(){
        }
        //初始化头节点
        public Node init(){
            return new Node(0,"");
        }
        //添加节点
        public void add(Node Head,Node newNode){
            //先创建个临时结点存放头结点,下面用这个Temp结点遍历,如果直接用Head结点遍历会丢失链表
            Node Temp = Head;//虽然Head的变量赋给了Temp,但他们共用一个地址,操作地址是同一个,这也是为什么在Temp里add元素,在head里也能加上,相当于Head和Temp共用new Node(0,"")
            /*
            * 
            * 如果能理解了为什么Temp与Head相等,就真正理解了链表了,这是理解链表的最后一步,因为如果前面的不理解,这个也很难理解
            * */
            System.out.println(Temp == Head);
            //第二步遍历结点,为的是找到尾结点,因为要从尾结点插入嘛
            while(true){
                if (Temp.next == null){
                  break;
                }
                Temp = Temp.next;
            }
            Temp.next = newNode;
        }

        //遍历结点
        public void Traverse(Node Head){
            if (Head.next == null){
                System.out.println("链表为空!");
                return;
            }
            Node Temp = Head.next;
            while(true){
                if (Temp == null){
                    System.out.println("已经遍历完链表啦!");
                    break;
                }
                System.out.println(Temp);
                Temp = Temp.next;
            }
        }
    }
    //结点类
    class Node{
        int no;//编号
        String name;//姓名
        Node next;//指针
        public Node(int no,String name){
            this.no = no;
            this.name = name;
        }
        @Override
        public String toString() {
            return "Node{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

1. 这段代码的大体结构是定义了个结点类(Node)和一个操作结点类(LinkedListOptions)方法都写在操作结点类里。

2. 在操作结点类里,有一个初始化(init())方法,返回的是头结点。

3. 还有一个add方法,参数是头结点和要插入的结点,这个方法实现的关键是把头结点(Head)赋给临时结点(Temp),直接操作头结点会破坏原始链表

       有人要问了,为什么操作Temp结点会对Head有影响,比如给Temp添加新结点,直接会添加到Head结点里?

这要说到java的内存结构了,也许你注意到了,在add方法里有一个System.out.println(Head==Temp),这句话到底是什么意思呢? 

初级链表简单案例—java版_第1张图片

图片引自java内存结构详解

以String为例,new String(“abc”)会把值放到堆里,并且会唯一分配一个地址

换句话说

String x = new String(“abc”); //x的地址是0x0038

String a = x;//把new String(“abc”)的地址赋给a了,所以a的地址也是0x0038

所以System.out.println(Head==Temp) 的值为true,因为他俩地址相同,但Head和Temp又是两个变量

如果是String x = new String (“abc”);

和String a = new String("abc");

System.out.println(x == a); // 值为false,x和a地址不相同

我理解的可能有错误,欢迎大佬来指正!

你可能感兴趣的:(数据结构与算法——java,链表,java,数据结构)