如何查看單鏈表是否有環?

查看鏈表是否有環?兩種方式

思路:就是因爲有環,所以是沒有尾節點,也就是 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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章