链表

单向链表

package one.linkedlist;

import java.util.Stack;

/**
 * @author : 赵兴宇
 */
public class SingleLinkedListDemo {

    public static void main(String[] args) {
        HeroNode node1 = new HeroNode(1, "宋亚楠", "songyanan");
        HeroNode node2 = new HeroNode(2, "刘吉昂", "liujiang");
        HeroNode node3 = new HeroNode(3, "侯强", "houqiang");
        HeroNode node4 = new HeroNode(4, "李四", "lisi");
        SingleLinkedList singleLinkedList = new SingleLinkedList();
//        singleLinkedList.add(node1);
//        singleLinkedList.add(node2);
//        singleLinkedList.add(node3);
        singleLinkedList.addByOrder(node2);
        singleLinkedList.addByOrder(node1);
        singleLinkedList.addByOrder(node4);
        singleLinkedList.addByOrder(node3);
        //System.out.println(node1);

        singleLinkedList.delNode(4);
        singleLinkedList.list();
        System.out.println("有效节点个数:" + singleLinkedList.length());

        System.out.println("倒数第n个节点:" + singleLinkedList.findLastNode(1));

        System.out.println("节点反转begin:");
        singleLinkedList.list();
        System.out.println("节点反转end:");
        singleLinkedList.reverseList();
        singleLinkedList.list();

        System.out.println("逆序打印");
        singleLinkedList.reverseOrderPrint();

    }

}

// 管理英雄信息
class SingleLinkedList {
    // 头结点
    private HeroNode head = new HeroNode(0, "", "");

    // 在尾结点添加一个元素
    public void add(HeroNode node) {
        HeroNode temp = head;
        // 直到遍历到最后的元素
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
    }

    // 遍历链表
    public void list() {
        if (head.next == null) {
            System.err.println("链表为空 。。。");
            return;
        }
        HeroNode heroNode = head.next;
        while (heroNode != null) {
            System.out.println(heroNode);
            heroNode = heroNode.next;
        }
    }

    // 添加元素并且排序
    public void addByOrder(HeroNode node) {
        HeroNode temp = head;
        boolean flag = false; // 添加的编号是否存在, 默认不存在
        while (true) {
            if (temp.next == null) {
                // 最后一个元素
                break;
            }
            if (temp.next.no > node.no) {
                // 如果下一个元素no比我大 ,那我就加载这里
                break;
            } else if (temp.next.no == node.no) {
                System.err.printf("add err 英雄【%d】存在\n", node.no);
                flag = true;
                break;
            }
            // 循环遍历
            temp = temp.next;
        }
        if (!flag) {
            // 插入元素
            node.next = temp.next;
            temp.next = node;
        }
    }

    // 删除节点
    public void delNode(int no) {
        HeroNode temp = head;
        while (true) { // 找到节点为止
            if (temp.next.no == no) {
                // flag = true;
                temp.next = temp.next.next;
                break;
            }
            temp = temp.next;
            if (temp.next == null) {
                System.err.println("要删除的节点未找到..." + no);
                return;
            }
        }
    }

    // 有效长度
    public int length() {
        HeroNode temp = this.head.next;
        int count = 0;
        while (temp != null) {
            temp = temp.next;
            count++;
        }
        return count;
    }

    // 找到倒数第 n 个节点并返回
    public HeroNode findLastNode(int n) {
        if (head.next == null) {
            // 链表为空
            return null;
        }
        int length = length();
        if (n > length || n <= 0) {
            return null;
        }
        HeroNode curr = head.next;
        for (int i = 0; i < length - n; i++) {
            curr = curr.next;
        }
        return curr;
    }

    // 链表反转
    public void reverseList() {
        if (head.next == null || head.next.next == null) {
            return;
        }
        HeroNode cur = head.next; // 当前节点
        HeroNode next = null;
        HeroNode reverseHead = new HeroNode(0, "", "");
        while (cur != null) {
            next = cur.next; // 暂存
            cur.next = reverseHead.next; //将cur的下一个节点移至新链表最前端
            reverseHead.next = cur;
            cur = next; // cur后移动
        }
        // 将head.next =指向 reverseHead.next , 实现单链表反转
        head.next = reverseHead.next;
    }

    // 逆序打印  压入栈 在依次输出
    public void reverseOrderPrint() {
        HeroNode curr = head.next;
        Stack<HeroNode> heroNodes = new Stack<>();
        while (curr != null) {
            // 将元素压入栈中
            heroNodes.push(curr);
            curr = curr.next;
        }
        // 再次输出栈中的数据
        while (!heroNodes.empty()) {
            System.out.println(heroNodes.pop());
        }
    }
}

// 英雄节点
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 + '\'' +
                /*", next=" + next +*/
                '}';
    }
}

双向两表

package one.linkedlist;

import java.util.Stack;

public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode2 node1 = new HeroNode2(1, "宋亚楠", "songyanan");
        HeroNode2 node2 = new HeroNode2(2, "权宇航", "quanyuhang");
        HeroNode2 node3 = new HeroNode2(3, "侯强", "houqiang");
        HeroNode2 node4 = new HeroNode2(4, "李四", "lisi");
        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();
        doubleLinkedList.add(node2);
        doubleLinkedList.add(node1);
        doubleLinkedList.add(node4);
        doubleLinkedList.add(node3);
        doubleLinkedList.delNode(2);
        doubleLinkedList.list();
    }
}

class DoubleLinkedList{
    // 头结点
    private HeroNode2 head = new HeroNode2(0, "", "");
    // 在尾结点添加一个元素
    public void add(HeroNode2 node) {
        HeroNode2 temp = head;
        // 直到遍历到最后的元素
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
        node.pre = temp;
    }

    // 遍历链表
    public void list() {
        if (head.next == null) {
            System.err.println("链表为空 。。。");
            return;
        }
        HeroNode2 HeroNode2 = head.next;
        while (HeroNode2 != null) {
            System.out.println(HeroNode2);
            HeroNode2 = HeroNode2.next;
        }
    }

    // 添加元素并且排序
    public void addByOrder(HeroNode2 node) {
        HeroNode2 temp = head;
        boolean flag = false; // 添加的编号是否存在, 默认不存在
        while (true) {
            if (temp.next == null) {
                // 最后一个元素
                break;
            }
            if (temp.next.no > node.no) {
                // 如果下一个元素no比我大 ,那我就加载这里
                break;
            } else if (temp.next.no == node.no) {
                System.err.printf("add err 英雄【%d】存在\n", node.no);
                flag = true;
                break;
            }
            // 循环遍历
            temp = temp.next;
        }
        if (!flag) {
            // 插入元素
            node.next = temp.next;
            temp.next = node;
        }
    }

    // 删除节点
    public void delNode(int no) {
        HeroNode2 temp = head.next;
        while (true) { // 找到节点为止
            if (temp.no == no) {
                // 1.将前一个next节点指向后一个节点的per
                temp.pre.next = temp.next;
                temp.next.pre = temp.pre;
                break;
            }
            temp = temp.next;
            if (temp.next == null) {
                System.err.println("要删除的节点未找到..." + no);
                return;
            }
        }
    }

    // 有效长度
    public int length() {
        HeroNode2 temp = this.head.next;
        int count = 0;
        while (temp != null) {
            temp = temp.next;
            count++;
        }
        return count;
    }

    // 找到倒数第 n 个节点并返回
    public HeroNode2 findLastNode(int n) {
        if (head.next == null) {
            // 链表为空
            return null;
        }
        int length = length();
        if (n > length || n <= 0) {
            return null;
        }
        HeroNode2 curr = head.next;
        for (int i = 0; i < length - n; i++) {
            curr = curr.next;
        }
        return curr;
    }

    // 链表反转
    public void reverseList() {
        if (head.next == null || head.next.next == null) {
            return;
        }
        HeroNode2 cur = head.next; // 当前节点
        HeroNode2 next = null;
        HeroNode2 reverseHead = new HeroNode2(0, "", "");
        while (cur != null) {
            next = cur.next; // 暂存
            cur.next = reverseHead.next; //将cur的下一个节点移至新链表最前端
            reverseHead.next = cur;
            cur = next; // cur后移动
        }
        // 将head.next =指向 reverseHead.next , 实现单链表反转
        head.next = reverseHead.next;
    }

    // 逆序打印  压入栈 在依次输出
    public void reverseOrderPrint() {
        HeroNode2 curr = head.next;
        Stack<HeroNode2> HeroNode2s = new Stack<>();
        while (curr != null) {
            // 将元素压入栈中
            HeroNode2s.push(curr);
            curr = curr.next;
        }
        // 再次输出栈中的数据
        while (!HeroNode2s.empty()) {
            System.out.println(HeroNode2s.pop());
        }
    }
}

// 英雄节点
class HeroNode2 {
    public int no;
    public String name;
    public String nickName;
    public HeroNode2 next; // 下一个节点
    public HeroNode2 pre;  // 前一个节点

    public HeroNode2(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode2{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
//                ", next=" + next +
//                ", pre=" + pre +
                '}';
    }
}

约瑟夫环问题

package one.linkedlist;

/**
 * @author : 赵兴宇
 * 约瑟夫环问题
 */
public class Josephus {
    public static void main(String[] args) {
        CircleSingleLinkedList linkedList = new CircleSingleLinkedList();
        linkedList.addBoy(4);
        linkedList.showBoy();
    }
}

class CircleSingleLinkedList {
    private Boy first = null;

    // 添加小孩节点,构建成一个环形的链表
    public void addBoy(int nums) {
        // nums 做一个数据校验
        if (nums < 1) {
            System.out.println("nums的值不正确");
            return;
        }
        Boy curBoy = null; // 辅助指针,帮助构建环形链表
        // 使用for来创建我们的环形链表
        for (int i = 1; i <= nums; i++) {
            // 根据编号,创建小孩节点
            Boy boy = new Boy(i);
            // 如果是第一个小孩
            if (i == 1) {
                first = boy; // 初始化 first 节点
                first.setNext(first); // 构成环
                curBoy = first; // 让curBoy指向第一个小孩
            } else {
                curBoy.setNext(boy); // 将 boy 节点加到链表尾部
                boy.setNext(first); // 构成环
                curBoy = boy; // curBoy 指针后移
            }
        }
    }

    // 遍历当前的环形链表
    public void showBoy() {
        // 判断链表是否为空
        if (first == null) {
            System.out.println("没有任何小孩~~");
            return;
        }
        // 因为first不能动,因此我们仍然使用一个辅助指针完成遍历
        Boy curBoy = first;
        while (true) {
            System.out.printf("小孩的编号 %d \n", curBoy.getNo());
            if (curBoy.getNext() == first) {// 说明已经遍历完毕
                break;
            }
            curBoy = curBoy.getNext(); // curBoy后移
        }
    }
}

class Boy {
    private int no;
    private Boy next;

    public Boy(int no) {
        this.no = no;
        this.next = null;
    }

    public void setNext(Boy next) {
        this.next = next;
    }

    public Boy getNext() {
        return next;
    }

    @Override
    public String toString() {
        return "Boy{" +
                "no=" + no +
//                ", next=" + next +
                '}';
    }

    public int getNo() {
        return no;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明明吃了饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值