如何查看单链表是否有环?

查看链表是否有环?两种方式

思路:就是因为有环,所以是没有尾节点,也就是 node.next 永远都是有值的。可以通过两个前进速度不同的节点去循环,如果有相遇的时刻说明有环。

  • 首先创建Node节点
private  class Node {
	private Object data;
	Node next;

	public Node() {
		data = null;
	}

	public Node(Object data) {
		this.data = data;
	}
}
  • 创建有环链表
    private Node createLink(){
        // 构造链表
        Node head = new Node();
        head.next = null;
        Node temp = null;
        Node cur = head;

        for (int i = 0; i < 10; i++) {
            temp = new Node();
            temp.data = i;
            temp.next = null;
            cur.next = temp;
            cur = temp;
        }
//        Node tem = head;
//        while (tem.next != null) {
//            tem = tem.next;
//            // 输出 0123456789
//            System.out.print(tem.data);
//        }
        // 添加环
        cur.next = head.next.next.next;
//        Node tem1 = head;
//        while (tem1.next != null) {
//            tem1 = tem1.next;
//            // 因为有了环。。无限输出。。。卡死输出台
//            System.out.print(tem1.data);
//        }
        return head;
    }
  • 方式一:查看是否有环 根据是否返回有具体的点 返回 null 代表无环
    private Node isLoop(Node head) {
        // 查看是否有环  思路:如果有环,快的和慢的一定会有一点碰到一起
        if (head == null || head.next == null) {
            return null;
        }
        Node slow = head.next;
        Node fast = head.next;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                return slow;
            }
        }
        return null;
    }
  • 方式二:通过HashMap ,将节点引用添加到 HaskMap 中,如果存在引用说明有环,不存在说明无环。
    private Node isLoopForHashMap(Node head) {
        HashSet<Node> hashSet = new HashSet<Node>();
        Node tem = head;
        while (tem.next != null) {
            tem = tem.next;
            if (hashSet.contains(tem)) {
                return tem;
            }
            hashSet.add(tem);
        }
        return null;
    }
  • 查找环的入口点
public Node findLoopNode(Node head, Node meetNode) {
        Node first = head.next;
        Node second = meetNode;
        while (first != second) {
            first = first.next;
            second = second.next;
        }
        return first;
    }
  • 调用如下
    @Test
    public void testLink() {
        // 创建链表
        Node head = createLink();
        // 查找是否有环 有环则返回头节点
        Node node = isLoop(head);
        // Node node = isLoopForHashMap(head);
        if (node == null) {
            System.out.println("无环");
        } else {
            System.out.println("有环");
        }
        Node meetNode = findLoopNode(head, node);
        System.out.println(meetNode.data);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章