【数据结构与算法(java)】单链表 +倒数第N个节点+反转链表+逆序打印

链表

  • 分为带头节点的链表和没有头结点的链表

单链表

//(带头结点)
public class SingleLinkedListDemo {

    public static void main(String[] args) {
        HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
        HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
        HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
        HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");

        SingleLinkedList singleLinkedList = new SingleLinkedList();
        // singleLinkedList.add(hero1);
        // singleLinkedList.add(hero2);
        // singleLinkedList.add(hero3);
        // singleLinkedList.add(hero4);

        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero2);
        singleLinkedList.addByOrder(hero3);

        HeroNode hero5 = new HeroNode(4, "Lin", "豹子头");

        singleLinkedList.update(hero5);
        singleLinkedList.del(1);
        singleLinkedList.list();
    }
}

class SingleLinkedList {

    private HeroNode head = new HeroNode(0, "", "");

    public void add(HeroNode heroNode) {
        HeroNode temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = heroNode;
    }

    public void list() {
        if (head.next == null) {
            return;
        }
        HeroNode temp = head.next;
        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }

    public void addByOrder(HeroNode heroNode) {
        HeroNode temp = head;
        while (temp.next != null) {
            if (temp.next.no > heroNode.no) {
                break; 
            } else if (temp.next.no == heroNode.no) {
                throw new RuntimeException("编号已存在");
            }
            temp = temp.next;
        }
        heroNode.next = temp.next;
        temp.next = heroNode;
    }

    public void update(HeroNode newHeroNode) {
        if (head.next == null) {
            return;
        }
        HeroNode temp = head.next;
        boolean flag = false;
        while (temp != null) {
            if (temp.no == newHeroNode.no) {
                temp.name = newHeroNode.name;
                temp.nickname = newHeroNode.nickname;
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (!flag) {
            throw new RuntimeException("找不到该编号的节点");
        }
    }

    public void del(int no) {
        HeroNode temp = head;
        boolean flag =false;
        while (temp.next!=null) {
            if (temp.next.no==no) {
                flag=true;
                temp.next=temp.next.next;
            }
            temp=temp.next;
        }
        if (!flag) {
            System.out.println("不存在该节点");
        }
    }
}

class HeroNode {

    public int no;
    public String name;
    public String nickname;
    public HeroNode next;

    public HeroNode(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
    }
}
  • 倒数第N个节点

        public static HeroNode findLastIndexNode(HeroNode head, int index) {
            if (head.next == null) {
                return null;
            }
            int length = getLength(head);
            if (index <= 0 || index > length) {
                return null;
            }
            HeroNode temp = head.next;
            int currentIndex = 0;
            while (temp != null) {
                currentIndex++;
                if (currentIndex == length + 1 - index) {
                    return temp;
                }
                temp = temp.next;
            }
            return null;
        }
    
    
  • 反转链表

    思路:

    1. 先定义一个节点 reverseHead = new HeroNode();
    2. 从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表 reverseHead 的最前端.
    3. 原来的链表的 head.next = reverseHead.next
    public static void reverseList(HeroNode head) {
        if (head.next == null || head.next.next == null) {
            return;
        }
        HeroNode newHead = new HeroNode(0, "", "");
        HeroNode cur = head.next;
        HeroNode next;
        while (cur != null) {
            next = cur.next;
            cur.next = newHead.next;
            newHead.next = cur;
            cur = next;
        }
        head.next = newHead.next;
    }
  • 逆序打印链表

    思路:

    1. 法一:先反转,再遍历(但是会破坏原有结构)

    2. 法二:可以利用栈(建议)

           public static void reversePrint(HeroNode head) {
               if (head.next==null) {
                   return;
               }
               Stack<HeroNode> stack = new Stack<>();
               HeroNode temp = head.next;
               while (temp!=null) {
                   stack.push(temp);
                   temp=temp.next;
               }
               while(!stack.empty()) {
                   System.out.println(stack.pop());
               }
           }
    
posted @ 2025-06-25 12:56  ToFuture$  阅读(8)  评论(0)    收藏  举报