惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

青空之蓝

[青空之蓝-2023] - 色彩 | 青空之蓝 [青空之蓝-2022] - 平静 | 青空之蓝 [青空之蓝-2021] - 远望 | 青空之蓝 浅谈垃圾回收 | 青空之蓝 浅谈泛型擦除 浅谈单点登录 使用 Kotlin 编写 Spring 测试 设计模式系列文章 从零实现一个 Java 微框架 - IoC | 青空之蓝 从零实现一个 Java 微框架 - 前言 浅谈 JVM:类加载 浅谈 IO 浅谈并发:synchronized & ReentrantLock 浅谈并发:CAS & AQS 浅谈并发:ThreadLocal 浅谈并发:三大特性 浅谈组合注解 & 注解别名 [青空之蓝-2020]-迷茫 Java 系列文章 HTTP 系列文章 | 青空之蓝 浅谈 EatWhatYouKill 浅谈可扩展线程池 聊聊写框架 | 青空之蓝 聊聊现状-[2020-09] | 青空之蓝 浅谈并发:锁 | 青空之蓝 浅谈并发:基础 | 青空之蓝 浅谈缓存 | 青空之蓝 无须定义类,Spring 快速注入 Json 参数 浅谈 Proxy 和 Aop 从零实现一个 PHP 微框架 - 初始化请求 为 Vue3 添加一个简单的 Store 从零实现一个 PHP 微框架 - 服务提供者 WSL2 踩坑记录 浅谈浏览器Event Loop [更新] | 青空之蓝 从零实现一个 PHP 微框架 - Bootstrap 启动加载 从零实现一个 PHP 微框架 - IoC 容器 从零实现一个 PHP 微框架 - PSR & Composer 从零实现一个 PHP 微框架 - 前言 MVVM 简单实现 浅谈 DI 和 IoC 中间件实现 [PHP] 告别 Windows 终端的难看难用,打造好用的 PowerShell VSCode Java输出中文乱码问题解决[更新] 浅谈浏览器渲染 Vue-Cli@2 项目迁移日志 Laragon & Scoop 集成踩坑记录 「一行代码」优雅管理 Windows 软件 [青空之蓝-2019]-年度总结 为Vue添加简单的Store 为React添加简单的Store 为Vuex添加同步Action 浅谈B+树 浅谈跳表 浅谈数据库索引 | 青空之蓝 MySQL事务隔离 算法复杂度分析(1) 一年来的经验总结 Acrylic - VSCode Extension ace编辑器设置惯性滚动 为apt方式安装的nginx重新编译增加WebDAV Java二叉树实现 Java图实现 XK-Editor - 一个支持富文本和Markdown的编辑器 JS生成列表树 | 青空之蓝 Laravel生成目录树 XK-Note - 集各种神奇功能的云笔记 PHP GD生成验证码 PHP GD图片处理[转换格式-水印-缩略图] | 青空之蓝 Origami - 简洁轻快的WordPress主题 为WordPress启用WorkBox Windows IP变化自动发送邮件 [青空之蓝-2018]-年度总结 VSCode Java手动导入jar和源码包 C 结构体的定义和使用 | 青空之蓝 C链表实现重制版 | 青空之蓝 图的搜索(遍历) - BFS & DFS C 快速排序 | 青空之蓝 C 归并排序 C 插入排序 C语言链表实现 VSCode配置Java调试环境[Windows] C 选择排序 C 冒泡排序 VSCode配置PHP调试环境[Windows] | 青空之蓝 VSCode配置C/C++ GDB调试环境[Windows] WordPress友情链接模板 Intel Optane 傲腾内存体验 | 青空之蓝 Mysql双机热备实战 博客一年记录 为WordPress启用Service Worker Bing每日一图API iframe延迟加载 写在2018年高考前 The Fox主题汉化分享 [青空之蓝-2017]-崭新 本博客评论规则 世界,您好!
Java链表实现 | 青空之蓝
2018-11-29 · via 青空之蓝

转换阵营 ing,大部分的介绍都在注释写了,这里就不再重复了,注释中没有关于链表的原理,如果还不懂链表的可以先去看其他教程,这里不写主要是我比较懒( ̄ ▽  ̄)"

之前的算法有问题,现在已经修改完成,并重写了部分代码,对数据域使用泛型,可以存放任何对象了,存放不同数据类型时就不再需要定义多个链表类了ヾ(≧▽≦*)o

这个算法还有优化的空间,不久后将升级,心急的可以看 C 链表重置版然后将其改成 Java 即可

package MyLinkedListDemo;

import java.util.Scanner;

public class MyLinkedListDemo {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        MyLinkedList<Integer> list = new MyLinkedList<Integer>();
        list.add(-1, 1);
        list.add(-1, 2);
        list.add(-1, 3);
        list.add(-1, 4);
        list.add(-1, 5);
        int a = list.get(2);
        System.out.println(a);
        in.close();
        }
    }

    class MyLinkedList<T> {

        //链表总长度
        int len = 0;
        // 头节点
        Node head = null;
        // 尾节点
        Node end = null;

        // 链表节点类(内部类)
        class Node {
            // 上一个节点
            Node prev;
            // 下一个节点
            Node next;
            // 数据块
            T data;

            // 空构造器,用于构造临时节点和定位节点等不需要使用数据块的节点
            Node() {
            };

            // 可填入数据的构造器,用填入数据
            Node(T data) {
                // 填入数据到数据块
                this.data = data;
            }
        }

        // 插入链表节点的方法
        // 参数i : 表示要插入的位置,当 i = -1 时新节点会被放置头位置,若 i = -2 时新节点会被放置至尾位置
        public void add(int i /* 要添加的位置,新节点会添加至该位置之后 */, T data /* 传入数据 */) {
            // 递增定位
            len++;
            int j;
            // 定义定位节点
            Node indexNode = head;
            // 创建新节点
            Node newNode = new Node(data);

            // 判断链表是否为空
            if (head == null) {
                // 若是只需将新节点设为头节点和尾节点就行
                head = newNode;
                end = newNode;
                return;
            }

            // Create Mode
            if (i == -1) // 头插法
            {
                newNode.next = head;
                head.prev = newNode;
                head = newNode;
                return;
            } else if (i == -2) // 尾插法
            {
                while (indexNode.next != null) {
                    indexNode = indexNode.next;
                }
            }

            // Insert Mode

            // 移动定位节点至指定位置
            for (j = 0; j < i && indexNode != null; j++) {
                indexNode = indexNode.next;
            }
            // 判断是否是添加至最后一个节点
            if (indexNode.next == null) {
                // 将上一个节点next指向新节点
                indexNode.next = newNode;
                // 将新节点的prev指向上一个节点
                newNode.prev = indexNode;
                // 将新节点的next指向null
                newNode.next = null;
                // 将新节点设为尾节点
                end = newNode;
                return;
            }
            // 创建临时节点用于存储原下一个节点的地址
            Node tempNode = indexNode.next;
            // 将上一个节点的next指向新节点
            indexNode.next = newNode;
            // 将新节点的next指向原下一个节点
            newNode.next = tempNode;
            // 将新节点的prev指向上一个节点
            newNode.prev = indexNode;
            // 将原下一个节点的prev指向新节点
            tempNode.prev = newNode;
        }

        // 插入带数据的链表到指定位置,操作方式同add,只是新增的节点是已经有数据的
        public void add(int i, Node haveNode) {
            len++;
            int j;
            Node indexNode = head;

            if (i == -1) {
                haveNode.next = head;
                head.prev = haveNode;
                head = haveNode;
                return;
            }

            for (j = 0; j < i && indexNode != null; j++) {
                indexNode = indexNode.next;
            }

            if (indexNode.next == null) {
                indexNode.next = haveNode;
                haveNode.prev = indexNode;
                haveNode.next = null;
                end = haveNode;
                return;
            }

            haveNode.next = indexNode.next;
            haveNode.next.prev = haveNode;
            haveNode.prev = indexNode;
            indexNode.next = haveNode;
        }

        // 删除指定节点
        // 参数 i : 当 i = 0 时代表删除第一个节点,i = -1 时代表删除最后一个节点
        public void delete(int i/* 要删除节点的位置 */) {
            len--;
            // 判断是否是删除第一个节点
            if (i == 0) {
                // 将头节点指向第二个节点,然后将头节点的prev设置为null,这样就屏蔽掉了第一个节点
                head = head.next;
                head.prev = null;
                return;
            }
            // 若是删除最后一个节点,那只需将尾节点移到倒数第二个节点即可
            else if (i == -1) {
                end = end.prev;
                end.next = null;
                return;
            }

            // 递增定位
            int j;
            // 创建定位节点,将其指向头节点
            Node indexNode = head;
            // 将定位节点移至要删除节点的上一个节点
            for (j = 0; j < i - 1 && indexNode != null; j++) {
                indexNode = indexNode.next;
            }
            // 判断要删除节点是否是最后一个节点
            if (indexNode.next.next == null) {
                // 操作方式同删除头节点与
                end = end.prev;
                end.next = null;
                return;
            }
            // 要删除节点的下一个节点prev设置为要删除节点的上一个节点
            indexNode.next.next.prev = indexNode;
            // 将要删除节点的上一个节点的next设置为要删除节点的下一个节点
            indexNode.next = indexNode.next.next;
        }

        // 清空链表
        public void clear() {
            len = 0;
            // 清空链表只需将头节点和尾节点设置为null即可,内存会由垃圾回收器回收
            head = null;
            end = null;
        }

        // 遍历输出链表数据
        public void print() {
            // 创建定位节点
            Node indexNode = head;
            // 使用while循环进行遍历
            while (indexNode != null) {
                // 输出数据
                System.out.print(indexNode.data.toString() + " ");
                // 移动定位节点
                indexNode = indexNode.next;
            }
            // 换行
            System.out.println();
        }

        // 链表逆置
        public void resever() {
            // 创建临时节点用来临时存储指向数据
            Node tempNode = new Node();
            // 将头节点与尾节点交换
            tempNode = head;
            head = end;
            end = tempNode;
            // 创建定位节点
            Node indexNode = head;
            // 循环交换next和prev数据
            while (indexNode.prev != null && (indexNode.next != null || indexNode == head)) {
                tempNode = indexNode.next;
                indexNode.next = indexNode.prev;
                indexNode.prev = tempNode;
                indexNode = indexNode.next;
            }
            // 设置最后一个节点的next为null
            end.next = null;
            // 设置最后一个节点的prev数据
            end.prev = tempNode.next;
        }

        // 添加新节点到列表末尾
        public void addFirst(T data) {
            this.add(-2, data);
        }

        // 添加新节点到列表头
        public void addLast(T data) {
            this.add(-1, data);
        }

        // 获取指定位置的数据
        public T get(int i) {
            Node indexNode = head;
            for (int j = 0; j < i; j++) {
                indexNode = indexNode.next;
            }
            return indexNode.data;
        }

    }
package MyLinkedListDemo;

import java.util.Scanner;

public class MyLinkedListDemo {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        MyLinkedList<Integer> list = new MyLinkedList<Integer>();
        list.add(-1, 1);
        list.add(-1, 2);
        list.add(-1, 3);
        list.add(-1, 4);
        list.add(-1, 5);
        int a = list.get(2);
        System.out.println(a);
        in.close();
        }
    }

    class MyLinkedList<T> {

        //链表总长度
        int len = 0;
        // 头节点
        Node head = null;
        // 尾节点
        Node end = null;

        // 链表节点类(内部类)
        class Node {
            // 上一个节点
            Node prev;
            // 下一个节点
            Node next;
            // 数据块
            T data;

            // 空构造器,用于构造临时节点和定位节点等不需要使用数据块的节点
            Node() {
            };

            // 可填入数据的构造器,用填入数据
            Node(T data) {
                // 填入数据到数据块
                this.data = data;
            }
        }

        // 插入链表节点的方法
        // 参数i : 表示要插入的位置,当 i = -1 时新节点会被放置头位置,若 i = -2 时新节点会被放置至尾位置
        public void add(int i /* 要添加的位置,新节点会添加至该位置之后 */, T data /* 传入数据 */) {
            // 递增定位
            len++;
            int j;
            // 定义定位节点
            Node indexNode = head;
            // 创建新节点
            Node newNode = new Node(data);

            // 判断链表是否为空
            if (head == null) {
                // 若是只需将新节点设为头节点和尾节点就行
                head = newNode;
                end = newNode;
                return;
            }

            // Create Mode
            if (i == -1) // 头插法
            {
                newNode.next = head;
                head.prev = newNode;
                head = newNode;
                return;
            } else if (i == -2) // 尾插法
            {
                while (indexNode.next != null) {
                    indexNode = indexNode.next;
                }
            }

            // Insert Mode

            // 移动定位节点至指定位置
            for (j = 0; j < i && indexNode != null; j++) {
                indexNode = indexNode.next;
            }
            // 判断是否是添加至最后一个节点
            if (indexNode.next == null) {
                // 将上一个节点next指向新节点
                indexNode.next = newNode;
                // 将新节点的prev指向上一个节点
                newNode.prev = indexNode;
                // 将新节点的next指向null
                newNode.next = null;
                // 将新节点设为尾节点
                end = newNode;
                return;
            }
            // 创建临时节点用于存储原下一个节点的地址
            Node tempNode = indexNode.next;
            // 将上一个节点的next指向新节点
            indexNode.next = newNode;
            // 将新节点的next指向原下一个节点
            newNode.next = tempNode;
            // 将新节点的prev指向上一个节点
            newNode.prev = indexNode;
            // 将原下一个节点的prev指向新节点
            tempNode.prev = newNode;
        }

        // 插入带数据的链表到指定位置,操作方式同add,只是新增的节点是已经有数据的
        public void add(int i, Node haveNode) {
            len++;
            int j;
            Node indexNode = head;

            if (i == -1) {
                haveNode.next = head;
                head.prev = haveNode;
                head = haveNode;
                return;
            }

            for (j = 0; j < i && indexNode != null; j++) {
                indexNode = indexNode.next;
            }

            if (indexNode.next == null) {
                indexNode.next = haveNode;
                haveNode.prev = indexNode;
                haveNode.next = null;
                end = haveNode;
                return;
            }

            haveNode.next = indexNode.next;
            haveNode.next.prev = haveNode;
            haveNode.prev = indexNode;
            indexNode.next = haveNode;
        }

        // 删除指定节点
        // 参数 i : 当 i = 0 时代表删除第一个节点,i = -1 时代表删除最后一个节点
        public void delete(int i/* 要删除节点的位置 */) {
            len--;
            // 判断是否是删除第一个节点
            if (i == 0) {
                // 将头节点指向第二个节点,然后将头节点的prev设置为null,这样就屏蔽掉了第一个节点
                head = head.next;
                head.prev = null;
                return;
            }
            // 若是删除最后一个节点,那只需将尾节点移到倒数第二个节点即可
            else if (i == -1) {
                end = end.prev;
                end.next = null;
                return;
            }

            // 递增定位
            int j;
            // 创建定位节点,将其指向头节点
            Node indexNode = head;
            // 将定位节点移至要删除节点的上一个节点
            for (j = 0; j < i - 1 && indexNode != null; j++) {
                indexNode = indexNode.next;
            }
            // 判断要删除节点是否是最后一个节点
            if (indexNode.next.next == null) {
                // 操作方式同删除头节点与
                end = end.prev;
                end.next = null;
                return;
            }
            // 要删除节点的下一个节点prev设置为要删除节点的上一个节点
            indexNode.next.next.prev = indexNode;
            // 将要删除节点的上一个节点的next设置为要删除节点的下一个节点
            indexNode.next = indexNode.next.next;
        }

        // 清空链表
        public void clear() {
            len = 0;
            // 清空链表只需将头节点和尾节点设置为null即可,内存会由垃圾回收器回收
            head = null;
            end = null;
        }

        // 遍历输出链表数据
        public void print() {
            // 创建定位节点
            Node indexNode = head;
            // 使用while循环进行遍历
            while (indexNode != null) {
                // 输出数据
                System.out.print(indexNode.data.toString() + " ");
                // 移动定位节点
                indexNode = indexNode.next;
            }
            // 换行
            System.out.println();
        }

        // 链表逆置
        public void resever() {
            // 创建临时节点用来临时存储指向数据
            Node tempNode = new Node();
            // 将头节点与尾节点交换
            tempNode = head;
            head = end;
            end = tempNode;
            // 创建定位节点
            Node indexNode = head;
            // 循环交换next和prev数据
            while (indexNode.prev != null && (indexNode.next != null || indexNode == head)) {
                tempNode = indexNode.next;
                indexNode.next = indexNode.prev;
                indexNode.prev = tempNode;
                indexNode = indexNode.next;
            }
            // 设置最后一个节点的next为null
            end.next = null;
            // 设置最后一个节点的prev数据
            end.prev = tempNode.next;
        }

        // 添加新节点到列表末尾
        public void addFirst(T data) {
            this.add(-2, data);
        }

        // 添加新节点到列表头
        public void addLast(T data) {
            this.add(-1, data);
        }

        // 获取指定位置的数据
        public T get(int i) {
            Node indexNode = head;
            for (int j = 0; j < i; j++) {
                indexNode = indexNode.next;
            }
            return indexNode.data;
        }

    }

Java链表实现

https://blog.ixk.me/post/java-linked-list-implementation
  • 许可协议

    BY-NC-SA

  • 本文作者

    Otstar Lin

  • 发布于

    2018/11/29

转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!

图的搜索(遍历) - BFS & DFSC 快速排序