单链表翻转、逆序打印、有序插入(java)

简介: 单链表翻转、逆序打印、有序插入(java)

节点

public class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;
 
    public HeroNode(int hNo, String hName, String hNickname) {
        no = hNo;
        name = hName;
        nickname = hNickname;
    }
 
    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
 
                '}';
    }
}

单链表

package org.minos.linkedlist;
 
import java.util.Stack;
 
public class SingleLinkedList {
    //初始化一个头结点,头结点作为一个标志位
    private HeroNode head = new HeroNode(0, "", "");
 
    /**
     * 添加一个节点
     *
     * @param heroNode
     */
    public void add(HeroNode heroNode) {
        HeroNode temp = head;
        while (true) {
            if (temp.next == null) {
                temp.next = heroNode;
                break;
            }
            temp = temp.next;
        }
    }
 
    //按照排序添加
    public void addByOrder(HeroNode heroNode) {
        HeroNode temp = head;
        //是否有重复
        boolean flag = false;
        int no = heroNode.no;
        while (true) {
            // 链表末尾跳出
            if (temp.next == null) {
                break;
            }
            if (no < temp.next.no) {
                break;
            } else if (no == temp.next.no) {
                flag = true;
            }
            temp = temp.next;
        }
        //没有重复的
        if (!flag) {
            heroNode.next = temp.next;
            temp.next = heroNode;
        } else {
            System.out.println("添加元素重复");
        }
    }
 
    //修改节点,编号不能修改
    public void update(HeroNode newHeroNode) {
        HeroNode tem = head.next;
        while (true) {
            if (tem == null) {
                break;
            }
            if (tem.no == newHeroNode.no) {
                tem.nickname = newHeroNode.nickname;
                tem.name = newHeroNode.name;
                break;
            }
            tem = tem.next;
        }
    }
 
    /**
     * 删除节点
     */
    public void delete(int no) {
        HeroNode tem = head;
        while (true) {
            if (tem.next == null) {
                break;
            }
            if (tem.next.no == no) {
                tem.next = tem.next.next;
                break;
            }
            tem = tem.next;
        }
    }
 
    //获取节点的长度
    public int length() {
        HeroNode tem = head;
        int length = 0;
        while (tem.next != null) {
            length++;
            tem = tem.next;
        }
        return length;
    }
 
    /**
     * 寻找倒数第N个节点     *
     *
     * @param index
     * @return
     */
    public HeroNode findLastIndexNode(int index) {
        int length = length();
        //空链表、输入不合理返回null
        if (head.next == null || index <= 0 || index > length) {
            return null;
        }
        HeroNode tem = head.next;
        for (int i = 0; i < length - index; i++) {
            tem = tem.next;
        }
        return tem;
    }
 
    /**
     * 使用栈的数据结构,先进后出,
     */
    public void reversePrint() {
        if (head.next == null) {
            return;
        }
        HeroNode cur = head.next;
        //创建一个容器
        Stack<HeroNode> stack = new Stack<HeroNode>();
        //将链表数据压入栈中
        while (cur != null) {
            stack.add(cur);
            cur = cur.next;
        }
        //将栈中的数据进行打印
        while (stack.size() > 0) {
            System.out.println(stack.pop());
        }
 
    }
 
    public void reverse() {
        //链表为空或者只有一个节点,无须翻转
        if (head.next == null || head.next.next == null) {
            return;
        }
        //当前节点
        HeroNode cur = head.next;
        //当前节点的下一个节点
        HeroNode next = null;
        //翻转后的头结点
        HeroNode reversHead = new HeroNode(0, "", "");
        while (cur != null) {
            //记录原链表的后一个节点
            next = cur.next;
            //将当前节点的后一个节点修改为反转后链表
            cur.next = reversHead.next;
            //将反转后链表的头,指向当前链表
            reversHead.next = cur;
            //修改当前链表
            cur = next;
        }
        head = reversHead;
    }
 
    public void list() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.next;
        while (true) {
            //判断是否到链表的最后
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }
}

测试

package org.minos.linkedlist;
 
public class SingleLinkedListDemo {
    public static void main(String[] args) {
        //SingleLinkedList linkedList=new SingleLinkedList();
        //linkedList.add(new HeroNode(1,"宋江",""));
        //linkedList.add(new HeroNode(2,"卢俊义",""));
        //linkedList.add(new HeroNode(3,"吴用",""));
        //linkedList.add(new HeroNode(4,"林冲",""));
        //linkedList.list();
 
        SingleLinkedList linkedList2=new SingleLinkedList();
        System.out.println(linkedList2.length());
        linkedList2.addByOrder(new HeroNode(2,"卢俊义",""));
        linkedList2.addByOrder(new HeroNode(1,"宋江",""));
        linkedList2.addByOrder(new HeroNode(9,"吴用",""));
        linkedList2.addByOrder(new HeroNode(4,"林冲",""));
        linkedList2.addByOrder(new HeroNode(3,"吴用",""));
        linkedList2.list();
        System.out.println();
        linkedList2.reversePrint();
        //linkedList2.list();
        //linkedList2.reverse();
        //linkedList2.list();
 
    }
}
相关文章
|
30天前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
38 3
|
1月前
|
存储 Java 开发者
HashSet和TreeSet教你重新认识Java集合的无序与有序
【10月更文挑战第14天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了它们分别实现无序和有序存储的机制。通过理解HashSet基于哈希表的无序特性和TreeSet利用红黑树实现的有序性,帮助开发者更好地选择合适的集合类型以满足不同的应用场景。
18 2
|
4月前
|
安全 Java 开发者
探索Java内存模型:可见性、有序性和并发
在Java的并发编程领域中,内存模型扮演了至关重要的角色。本文旨在深入探讨Java内存模型的核心概念,包括可见性、有序性和它们对并发实践的影响。我们将通过具体示例和底层原理分析,揭示这些概念如何协同工作以确保跨线程操作的正确性,并指导开发者编写高效且线程安全的代码。
|
4月前
|
设计模式 安全 Java
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
78 1
|
4月前
|
安全 Java 开发者
Java面试题:Java内存模型解析,Java内存模型的基本概念和它的重要性,Java内存模型中的“可见性”和“有序性”,以及具体实现?
Java面试题:Java内存模型解析,Java内存模型的基本概念和它的重要性,Java内存模型中的“可见性”和“有序性”,以及具体实现?
58 1
|
5月前
|
缓存 Java 程序员
Java内存模型深度解析:可见性、有序性和原子性
在多线程编程中,正确理解Java内存模型对于编写高效且无bug的并行程序至关重要。本文将深入探讨JMM的三大核心特性:可见性、有序性和原子性,并结合实例分析如何利用这些特性来避免常见的并发问题。
59 1
|
4月前
|
存储 缓存 安全
Java面试题:介绍一下jvm中的内存模型?说明volatile关键字的作用,以及它如何保证可见性和有序性。
Java面试题:介绍一下jvm中的内存模型?说明volatile关键字的作用,以及它如何保证可见性和有序性。
36 0
|
4月前
|
存储 安全 Java
Java面试题:Java内存模型中的主内存与工作内存是如何协同工作的?请解释Java内存模型中的可见性、原子性和有序性,举例说明Java内存模型中的happens-before关系
Java面试题:Java内存模型中的主内存与工作内存是如何协同工作的?请解释Java内存模型中的可见性、原子性和有序性,举例说明Java内存模型中的happens-before关系
36 0
|
5月前
|
存储 缓存 Java
【Java并发基础】Java内存模型解决有序性和可见性
【Java并发基础】Java内存模型解决有序性和可见性
|
12天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。