ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA学习记录(九)—— 无头单向非循环链表

2021-01-02 16:32:59  阅读:135  来源: 互联网

标签:Node 结点 JAVA cur 单向 head next 链表


链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的。

无头单向非循环链表实现与基本操作:

class Node{
    public int val;   //结点的val值
    public Node next; // 指向下一个结点的next
    public(){}        // 无参构造
    public(int val){  // 有参构造
        this.val = val;
    } 
}

public class MyLinkList{
    public Node head; //head是MyLinkList的成员变量
    
    // 一、创建链表的函数
    public void creatLinkList(){
        // 创建结点
        this.head = new Node(10); //Node()中填写的是该结点的val值
        Node node2 = new Node(20);
        Node node3 = new Node(30);
        Node node4 = new Node(40);
        // 将每个节点都连接起来
        this.head.next = node2;
        node2.next = node3;
        node3.next = node4;
    }
    
    // 二、打印链表
    public void PrintLinkList(){
        Node cur = this.head;
        while(cur != null){     // 这里使用 (cur != null)作为循环条件是因为我们为了打印该结点,即我们需要循环进入该结点
            System.out.print(cur.val + " ");
            cur = cur.next;     //这个遍历的方法是通过将cur这个引用的后一位的地址赋给cur这个引用,让其指向后一位的结点,以到达向后移动一位的效果
        }
        System.out.println();
    }
    
    // 三、找到链表的最后一个结点
    //     1、首先判断链表是否为空链表,如果为空链表,则没有最后一个结点
    //     2、再判断链表是否只有一个结点
    //     3、排除上面两个条件后,我们通过创建一个cur引用来遍历我们的链表
    //        因为在链表中,最后一个结点next部分指向的是null,所以我们使用while循环判断,当循环判断最后一个结点时为false,不进入while循环
    //        不进入循环,cur引用就不会再向后移动,此时的cur就是我们想要得到的最后一位结点的引用,返回cur即可。
    public Node findLastNode(){
        if(this.head == null){
            System.out.println("链表为空");
            return null;
        }
        if(this.head.next == null){
            System.out.println("该链表只有一个元素");
            return this.head;
        }
        Node cur = this.head;
        while(cur.next != null){
            cur = cur.next;
        }
        return cur;
    }
    
    // 四、找到链表的倒数第二个结点
    public Node findLastTwoNode(){
       if(this.head == null){
           System.out.println("该链表为空")
           return null;
       }
       if(this.head.next == null){
           System.out.println("该链表只有一个结点")
           return null;
       }
       Node cur = this.head;
       while(cur.next.next != null){
           cur = cur.next;
       }
       return cur;
    }
    
    // 五、找到链表中的第n个结点
    //     1、判空
    //     2、判断所给定的n是否合法,则需要知道链表的长度
    public int sizeNode(){
        int count = 0;
        Node cur = this.head;
        while(cur != null){
            count++;
            cur = cur.next;
        }
        return count;
    }
    //     2、通过while循环额外定义一个参数count来记录当前所处节点数
    public Node FindNode(int n){
        if(this.head == null){
            System.out.println("链表为空");
            return null;
        }
        if(n < 0 || n > sizeNode()){
            System.out.println("输入n不合法");
            return null;
        }
        Node cur = this.head;
        int count = 1;
        while(count != n){
            cur = cur.next;
            count++;
        }
        return cur;
    }
    
    // 六、链表中是否包含某个元素
    public boolean findKey(int key){
        if(this.head == null){
            System.out.println("链表为空");
            return null;
        }
        Node cur = this.head;
        while(cur != null){
            if(cur.val == key){
                return true;
            }
        }
        return false;
    }
    
    // 七、头插法
    public void addFirst(int data){
        Node node= new Node(data);   // 首先需要新建一个node结点
        if(this.head == null){       // 如果该链表为空链表
            this.head = node;        // 则让新生成的这个结点作为该链表的第一个结点
            return;
        }else{                       // 如果链表不为空
            node.next = this.head;   // 将新结点的next指向原链表的第一个结点的地址
            this.head = node;        // 之后将新的node结点作为整个链表新的第一个结点
        }
    }
    
    // 八、尾插法
    public void addLast(int data){
        Node node = new Node();
        if(this.head == null){       //常规判空
            this.head = node;        
            return;
        }else{
		     Node cur = this.head;        // 因为要尾插,所以我们要遍历一次链表到最后一位
		     while(cur.next != null){
		         cur = cur.next;
		     }
		     cur.next = node;
        }
    }
    
    // 九、在任意位置插入,基础假定第一个结点位置下标为0
    //     1、首先我们要判断所给的位置是否合法
    //     2、为了在index位置处插入一个结点,我们则必须找到链表中第index-1结点位置的引用
    public Node findIndexReduceOne(int index){
        Node cur = this.head;
        int count = 1;
        while(count != index-1){
            cur = cur.next;
            count++;
        }
        return cur;
    }
    //     3、将index-1位置结点的next指向新的结点node的地址,再将新结点node的next指向原本index-1结点所指向的next地址处
    public void addIndex(int index, int data){
        Node node = new Node(data);
        if(index < 0 || index > sizeNode()){
            System.out.println("输入index不合法");
            return;
        }
        if(index = 0){  //头插法
            addFirst(data);
            return;
        }
        if(index = sizeNode()){ //尾插法
            addLast(data);
            return;
        }
        Node prev = findIndexReduceOne(index);
        node.next = prev.next;
        prev.next = node;
    }
        
    // 十、删除第一次出现关键字key的结点(也可以通过写一个函数找到key结点的前驱结点)
    public void remove(int key){
        if(this.head == null){
            System.out.println("链表为空")
            return;
        }
        if(this.head.val == key){
            this.head = this.head.next;
            return;
        }
        Node cur = this.head;
        while(cur != null){
            if(cur.next.val == key){
                cur.next == cur.next.next;
                return;
            }
        }
    }
    
    // 十一、删除所有值为k的结点
    //     1、通过定义两个结点的方法,一个cur用来遍历整个链表与key进行比对,看所所遍历的此处结点是否需要删除
    //     2、另一个结点用来作为遍历结点的前驱结点prev
    //     3、为了遍历整个链表,所以循环条件应为(cur != null)
    public void removeAllKey(int key){
        Node prev = this.head; //节点一:用作要删除节点的前驱节点
        Node cur = prev.next;  //节点二:用来遍历整个链表的结点,
                               //须注意的是,我们这个cur结点是从链表的第二位开始遍历的,所以在执行完遍历删除操作后要再对第一个结点进行判断,看是否需要删除
        while(cur != null){
            if(cur.val == key){
                prev.next = cur.next;
            }else{
                prev = cur;
            }
            cur = cur.next;
        }
        //执行完上述操作后,还需对链表的第一个结点进行判断
        if(this.head.val == key){
            this.head = this.head.next;
        }
    }
    
    // 十二、清除链表
    public clear(){
        this.head == null;  //清除链表只需要将该链表的第一个结点置为null则链表就会自动被清除
    }
}

标签:Node,结点,JAVA,cur,单向,head,next,链表
来源: https://blog.csdn.net/MercuryG/article/details/112095231

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有