六、判斷兩個單向連結串列是否相交
阿新 • • 發佈:2018-12-15
判斷兩個單向連結串列是否相交,有兩種情況,一種是兩個不帶環的單向連結串列相交,一種是兩個帶環的單向連結串列相交。
情況1:兩個不帶環的單向連結串列相交
/*判斷兩個不帶環的單向連結串列是否相交。時間複雜度O(n),空間複雜度O(1)*/ /*思路:如果兩個沒有環的連結串列相交於某一節點,那麼在這個節點之後的*/ /*所有節點都是兩個連結串列共有的,如果它們相交,則最後一個節點一定是共有的*/ int is_intersect(struct list_head *head_one, struct list_head *head_two) { if (!head_one || !head_two) return -1; /*先找到連結串列1的尾節點*/ while (head_one->next != NULL) head_one = head_one->next; /*找連結串列2的尾節點並比較*/ while (head_two->next != NULL) { head_two = head_two->next; /*判斷尾節點是否相同*/ if (head_one == head_two) return 1;/*相交*/ } return 0;/*相交*/ }
情況2:兩個帶環的單向連結串列相交
/*判斷兩個帶環的單向連結串列是否相交*/ /*思路:如果有環且兩個連結串列相交,則兩個連結串列都有共同一個環,即環上的任意一個節點都存在*/ /*於兩個連結串列上。因此,就可以判斷一連結串列上倆指標相遇的那個節點,在不在另一條連結串列上。*/ int is_intersect(struct list_head *head_one, struct list_head *head_two) { struct list_head *slow = head_one; struct list_head *fast = head_one; struct list_head *temp = NULL; if (!head_one || !head_one->next || !head_two || !head_two->next) return -1; /*判斷連結串列1有沒有環,並得到連結串列1的環內節點(兩指標相遇的那個節點)*/ while (head_one != NULL || head_one->next != NULL) { slow = slow->next; fast = fast->next->next; if (slow == fast) {/*有環*/ temp = slow; /*獲取連結串列1的環內節點*/ break; } } if (slow != fast)/*連結串列1沒有環*/ return -1; /*判斷連結串列2有沒有環*/ slow = head_two; fast = head_two; while (head_two != NULL || head_two->next != NULL) { slow = slow->next; fast = fast->next->next; if (slow == fast)/*有環*/ break; } if (slow != fast)/*連結串列2沒有環*/ return -1; /*這裡的slow、fast都為連結串列2的環內節點,現在遍歷這個環,看連結串列1的環內節點temp在不在這個環上*/ slow = slow->next; while (slow != fast) { if (slow == temp) return 1;/*相交*/ slow = slow->next; } return 0;/*不相交*/ }