LeetCode算法学习笔记 - Day3

Java单链表的实现

  • 初级算法学习到了链表的操作…结果发现我连链表是啥都不知道…只能开始学了
    单链表很简单,一个对象里存数据然后有个指针指向下一个对象(说的不对大佬纠正我…反正我就这么理解的)

    话不多说直接上代码
这个是结点类


public class Node {
    public int data;
    public Node next;

    public Node(){

    }

    public Node (int data){
        this.data = data;
    }
}
单链表的增删改查..都写了注释

public class Test {
    private Node head;

    public Test(){
        head = new Node(100); //无参构造自动为0
    }

    /**
     * 添加结点到链表末尾
     * @param node
     */
    public void addNode(Node node){
        Node temp = head; //初始为头结点(是一个移动的指针指向当前遍历的结点)
        while (temp.next != null){ //遍历链表
            temp = temp.next; //如果当前节点的next不为null.那么temp(移动的指针)就等于当前遍历的结点.直到当前遍历的结点的next为null就跳出循环
        }
        temp.next = node;
    }

    /**
     * 根据index索引获得数据
     * @param index
     * @return
     */
    public int get(Integer index){
        Node temp = head; //初始为头结点(是一个移动的指针指向当前遍历的结点)
        int now = 0; //当前遍历的索引
        if (index == 0){ //如果索引为0就直接返回头部data
            return temp.data;
        }
        while (temp.next != null){ //遍历
            temp = temp.next; //每遍历一次temp就变为该次遍历的结点
            now++; //索引+1
            if (now == index){ //如果当前索引与index索引相同就返回当前索引数据
                return temp.data;
            }
        }
        return -1; //没有该索引就返回-1
    }

    /**
     * 在头结点前添加数据作为新的头结点
     * @param node
     */
    public void addAtHead(Node node){
        Node temp = head; //存储头结点
        head = node; //重定义头结点
        head.next = temp; //将原头结点添加到下一个
    }

    /**
     * 在链表中的第index个节点之前添加值为node的节点
     * 如果index等于链表的长度,则该节点将附加到链表的末尾
     * 如果 index 大于链表长度,则不会插入节点
     * 如果index小于等于0,则在头部插入节点。
     * @param index
     * @param node
     */
    public void addAtIndex(Integer index,Node node){
        if (index <= 0){
            addAtHead(node);
        }
        if (index > length()){
            System.out.println("超过链表长度");
        }
        if (index == length()){
            addNode(node);
        }
        else {
            Node temp = head; //初始为头结点(是一个移动的指针指向当前遍历的结点)
            int now = 0; //当前遍历的索引
            while (temp.next != null){ //遍历
                now++; //索引自增
                if (index == now){ //如果index索引等于当前索引(此时的指针还未修改)
                    node.next = temp.next; //node的右指针为上一个结点的右指针
                    temp.next = node; //上一个结点的右指针指向node
                    break; //跳出遍历
                }
                temp = temp.next; //每遍历一次temp就变为该次遍历的结点
            }
        }
    }

    /**
     * 如果索引index有效,则删除链表中的第index个节点。
     * @param index
     */
    public void deleteAtIndex(Integer index){
        if (index == 0){ //index索引等于0就把头部变为原头部的右指针
            head = head.next;
        }
        Node temp = head;//初始为头结点(是一个移动的指针指向当前遍历的结点)
        int now = 0; //当前遍历的索引
        if (index >=0 && index <= length()){
            while (temp.next != null){ //遍历
                now++; //索引自增
                if (index == now){ //匹配当前索引
                    if (index == length()){ //如果index索引是该链表的最后一个就设为null
                        temp.next = null;
                        break;
                    }
                    temp.next = temp.next.next;
                    break;
                }
                temp = temp.next; //每遍历一次temp就变为该次遍历的结点
            }
        }else { //索引无效
            System.out.println("该索引无效");
        }
    }



    /**
     * 计算单链表的长度,也就是有多少个结点
     * @return    结点个数
     */
    public int length() {
        int length=0;
        Node temp = head;
        while(temp.next != null){
            length++;
            temp = temp.next;
        }
        return length;
    }

    /**
     * 遍历单链表,打印所有data
     */
    public void print(){
        Node temp = head.next;
        while(temp != null){
            System.out.println(temp.data+",");
            temp = temp.next;
        }
    }

}

这就是测试类了



import java.math.BigInteger;
import java.util.ArrayList;

@SuppressWarnings("SpellCheckingInspection")
public class LeetCode {
    public static void main(String[] args) {
        Test test = new Test();
        for (int i = 0; i < 10; i++) {
            Node node = new Node(i);
            test.addNode(node);
        }
        /**
         * 在头结点前添加并修改为头结点
        Node node = new Node(999);
        test.addAtHead(node);
         */

        /**
         * 在链表中的第index个节点之前添加值为node的节点
         * 如果index等于链表的长度,则该节点将附加到链表的末尾
         * 如果 index 大于链表长度,则不会插入节点
         * 如果index小于等于0,则在头部插入节点。
        Node node = new Node(2005);
        test.addAtIndex(1,node);
         */

        /**
         * 如果索引index有效,则删除链表中的第index个节点。
         test.deleteAtIndex(1);
         */
        System.out.println(test.get(0)); //第0个结点返回-1 第1个结点返回0 第2个结点返回1 ......
        System.out.println(test.get(1));
        System.out.println(test.get(2));
        System.out.println(test.get(3));
        System.out.println(test.get(4));
        System.out.println(test.get(5));
        System.out.println(test.get(6));
        System.out.println(test.get(7));
        System.out.println(test.get(8));
        System.out.println(test.get(9));
        System.out.println(test.get(10));
        System.out.println(test.get(11));
        System.out.println(test.length());
    }
}


小总结:

  • 链表存储不如ArrayList来的方便,而且查询某个索引的时候需要全部去遍历
  • 链表的优势在于可以方便的在链表中间插入数据,效率大大高于ArrayList
  • 各有各的好叭…
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值